UNPKG

@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,364 lines (1,351 loc) • 1.84 MB
import { Vector2 as Z, Vector3 as _, Vector4 as ge, Quaternion as V, PlaneGeometry as Cn, WebGLRenderer as Fr, PerspectiveCamera as de, OrthographicCamera as fu, Scene as Xi, Mesh as H, Texture as xe, Uniform$1 as Hi, Color as re, ShaderMaterial as qn, Box3 as zt, ShadowMaterial as fv, Euler as ct, MeshStandardMaterial as pt, Box3Helper as oS, GridHelper as pv, Object3D as M, Material as be, Matrix3 as mv, Matrix4 as ee, Layers as Co, Ray as As, MathUtils as Ps, AxesHelper as Pi, MeshBasicMaterial as Se, DoubleSide as Oi, BufferGeometry as _n, Group as ks, CylinderGeometry as gv, SphereGeometry as pu, BoxGeometry as Fa, SpriteMaterial as rS, Sprite as aS, Shape as lS, ExtrudeGeometry as cS, Fog as yv, DirectionalLight as $p, PointLight as Km, TextureLoader as Or, EdgesGeometry as hS, LineSegments as _v, LineBasicMaterial as Zm, Line as za, BufferAttribute as mt, Raycaster as mu, Sphere as gu, ArrayCamera as dS, Plane as Mr, SkinnedMesh as _o, InterleavedBufferAttribute as bv, Skeleton as uS, Bone as fS, WebGLCubeRenderTarget as pS, CubeCamera as mS, AnimationClip as ki, FileLoader as Jm, PropertyBinding as Ua, KeyframeTrack as gS, LinearSRGBColorSpace as Is, ShaderChunk as Jt, DataTexture as eg, RGBAFormat as yu, EquirectangularReflectionMapping as Os, SRGBColorSpace as Ls, Clock as yS, NeutralToneMapping as Na, AgXToneMapping as _u, ACESFilmicToneMapping as bu, NoToneMapping as Rd, PCFSoftShadowMap$1 as _S, BasicNodeLibrary as bS, WebGLRenderTarget as Xn, DepthTexture as vv, NearestFilter as Td, LoopRepeat as vS, LoopOnce as Wp, AnimationMixer as tg, CompressedTexture as wS, FrontSide as Po, Camera as xS, Frustum as Uy, AudioListener as SS, PositionalAudio as CS, AudioLoader as Vp, EventDispatcher as ig, BackSide as vu, MeshDepthMaterial as PS, CustomBlending as kS, MaxEquation as OS, AlwaysStencilFunc as MS, GreaterEqualStencilFunc as ES, NotEqualStencilFunc as RS, GreaterStencilFunc as TS, LessEqualStencilFunc as AS, EqualStencilFunc as IS, LessStencilFunc as LS, NeverStencilFunc as Ny, InvertStencilOp as DS, DecrementWrapStencilOp as jS, IncrementWrapStencilOp as BS, DecrementStencilOp as FS, IncrementStencilOp as zS, ReplaceStencilOp as US, ZeroStencilOp as NS, KeepStencilOp as $S, CubeUVReflectionMapping as wv, CubeTexture as xv, AmbientLight as WS, HemisphereLight as VS, Loader as HS, RawShaderMaterial as Sv, GLSL3 as GS, AlwaysDepth as qS, GreaterEqualDepth as XS, GreaterDepth as QS, LessEqualDepth as YS, LessDepth as KS, NotEqualDepth as ZS, EqualDepth as JS, BatchedMesh as $y, LinearFilter as Ad, UnsignedByteType as eC, MeshPhysicalMaterial as Wy, RingGeometry as tC, Line3 as iC, AdditiveBlending as Cv, BoxHelper as nC, SpotLight as sC, DirectionalLightHelper as oC, CameraHelper as rC, LOD as aC, Triangle as lC, NormalBlending as cC, ReinhardToneMapping as ng, LinearToneMapping as sg, HalfFloatType as Ef, VideoTexture as hC, CompressedCubeTexture as dC, EquirectangularRefractionMapping as uC, CatmullRomCurve3 as fC, VectorKeyframeTrack as pC, QuaternionKeyframeTrack as mC, Audio as gC, ShaderLib as Id, UniformsUtils as Pv, MirroredRepeatWrapping as Vy, MeshNormalMaterial as yC, AudioContext as _C, PMREMGenerator$1 as bC } from "./three.js"; import { createLoaders as og, getRaycastMesh as kv, LODsManager as Zo, NEEDLE_progressive as We, addDracoAndKTX2Loaders as vC, configureLoader as wC, setKTX2TranscoderLocation as xC, setDracoDecoderLocation as SC } from "./gltf-progressive-CzxjNmG6.js"; import { GroundedSkybox as $a, Font as CC, TextGeometry as PC, FontLoader as kC, GLTFLoader as Ds, TransformControlsGizmo as Ov, EXRLoader as rg, RGBELoader as Mv, Stats as OC, nodeFrame as Hy, OrbitControls as MC, PositionalAudioHelper as EC, HorizontalBlurShader as RC, VerticalBlurShader as TC, GLTFExporter as Ev, strToU8 as Rv, zipSync as AC, XRControllerModelFactory as IC, XRHandMeshModel as LC, Line2 as DC, LineGeometry as jC, LineMaterial as BC, TransformControls as FC, InteractiveGroup as zC, HTMLMesh as UC, VertexNormalsHelper as NC, OBJLoader as ag, FBXLoader as Tv, mergeVertices as $C } from "./three-examples.js"; import { fetchProfile as WC, MotionController as VC, $70d766613f57b014$export$2e2bcd8739ae039 as Gy, ByteBuffer as HC, v5 as qy, md5 as Xy, SIZE_PREFIX_LENGTH as Av, Builder as lg, createNoise4D as GC, Matrix4 as Rf, BatchedParticleRenderer as qC, ParticleSystem as XC, RenderMode as ps, ConstantColor as QC, Vector4 as YC, ConstantValue as KC, TrailParticle as Qy, WorkerBase as ZC, MeshBVH as JC } from "./vendor-BsRxp-FT.js"; import { __webpack_exports__default as Pe, __webpack_exports__Text as Iv, __webpack_exports__Block as Lv, __webpack_exports__update as e1, SimpleStateBehavior as t1, __webpack_exports__Inline as Tf, __webpack_exports__FontLibrary as Yy, ThreeMeshUI as Ky } from "./three-mesh-ui-B-lqrZWj.js"; import { EffectAttribute as i1 } from "./postprocessing-BUS23YkY.js"; const Af = /* @__PURE__ */ new Map(); function Qi(s = globalThis.location?.hostname) { if (Af.has(s)) return Af.get(s); const e = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s); return Af.set(s, e), e === !0; } function n1() { return window.location.hostname.includes("glitch.me"); } const Zy = typeof window !== void 0 ? 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 pe { /** 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 && (Zy && 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 && (Zy && 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) { this._callbacks[e] || (this._callbacks[e] = []), this._callbacks[e].push(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 s1 = () => (s) => s; function sD(s) { return s1()(s); } function oD() { return !!x("debug"); } class Yi { _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 dr = !1; const Hp = new Array(); typeof window < "u" && setTimeout(() => { if (dr) { 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 Hp) { 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 = dr === !0 ? "" : ` (containing "${dr}")`; console.group("Available URL parameters:" + n); for (const o of Object.keys(s).sort()) typeof dr == "string" && !o.toLowerCase().includes(dr.toLowerCase()) || (console.groupCollapsed(o), console.log("Reload with this flag enabled:"), console.log(s[o]), console.groupEnd()); console.groupEnd(); } }, 100); function wu() { return new URLSearchParams(globalThis.location?.search); } function x(s) { dr && !Hp.includes(s) && Hp.push(s); const e = wu(); 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; } dr = x("help"); function rD(s, e) { const t = wu(); t.has(s) ? t.set(s, e) : t.append(s, e), document.location.search = t.toString(); } function Ld(s, e, t = !0) { const i = wu(); i.has(s) ? e === null ? i.delete(s) : i.set(s, e) : e !== null && i.append(s, e), t ? o1(s, i) : Dv(s, i); } function Jy(s, e, t) { s.has(e) ? s.set(e, t.toString()) : s.append(e, t.toString()); } function o1(s, e, t) { window.history.pushState(t, s, "?" + e.toString()); } function Dv(s, e, t) { window.history.replaceState(t, s, "?" + e.toString()); } function aD(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 lD(s, e) { return Math.floor(Math.random() * (e - s + 1)) + s; } const e_ = ["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"], t_ = ["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 r1() { const s = e_[Math.floor(Math.random() * e_.length)], e = t_[Math.floor(Math.random() * t_.length)]; return s + "_" + e; } function a1(s) { return s = s.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, ""), s.trim(); } function Ec(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 = Ec(s, o, t, i); if (r) return r; } if (e.children) for (const n in e.children) { const o = e.children[n], r = Ec(s, o, t, i); if (r) return r; } } } function xu(s, e) { if (s != null && typeof s == "object") { let t; Array.isArray(s) ? t = [] : (t = Object.create(s), Object.assign(t, s)); for (const i of Object.keys(s)) { const n = s[i]; e && !e(s, i, n) ? t[i] = n : n?.clone !== void 0 && typeof n.clone == "function" ? t[i] = n.clone() : t[i] = xu(n, e); } return t; } return s; } function ko(s) { return new Promise((e, t) => { setTimeout(e, s); }); } function Su(s, e) { if (s <= 0) return Promise.resolve(); if (e || (e = pe.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 kh = x("debugresolveurl"), l1 = "rel:"; function cD(s, e) { return Eo(s, e); } function Eo(s, e) { if (e === void 0) return kh && console.warn("getPath: uri is undefined, returning uri", e), e; if (e.startsWith("./")) return e; if (e.startsWith("http")) return kh && console.warn("getPath: uri is absolute, returning uri", e), e; if (s === void 0) return kh && console.warn("getPath: source is undefined, returning uri", e), e; e.startsWith(l1) && (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 kh && console.log("source:", s, `changed uri from`, e, ` to `, n, ` basePath: ` + i), n; } return e; } function c1(s) { if (s) return s = s.trim(), s = s.split("?")[0]?.split("#")[0], s; } class h1 { 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 bo { _watches = []; constructor(e, t) { if (Array.isArray(t)) for (const i of t) this._watches.push(new bo(e, i)); else this._watches.push(new h1(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 ha = /* @__PURE__ */ Symbol("needle:watches"); function cg(s, e) { if (!s[ha]) if (s instanceof Z) s[ha] = new bo(s, ["x", "y"]); else if (s instanceof _) s[ha] = new bo(s, ["x", "y", "z"]); else if (s instanceof ge || s instanceof V) s[ha] = new bo(s, ["x", "y", "z", "w"]); else return !1; return s[ha].subscribeWrite(e), !0; } function jv(s, e) { if (!s) return; const t = s[ha]; t && t.unsubscribeWrite(e); } var D; ((s) => { let e; function t() { if (e !== void 0) return e; const J = window.navigator.userAgent, ke = /Windows|MacOS|Mac OS/.test(J), ri = /Windows NT/.test(J) && /Edg/.test(J) && !/Win64/.test(J); return e = ke && !ri && !T(); } 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 J = navigator.userAgent.toLowerCase(); return r = /iPad/.test(navigator.userAgent) || J.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 f; function p() { return f !== void 0 ? f : f = /NeedleAppClip\//i.test(navigator.userAgent); } s.isNeedleAppClip = p; let g; function y() { if (g !== void 0) return g; if (T() || a()) return g = !1; const J = navigator.userAgent.toLowerCase(); return navigator.userAgentData ? g = navigator.userAgentData.platform === "macOS" : g = J.includes("mac os x") || J.includes("macintosh"); } s.isMacOS = y; let m; function w() { return m !== void 0 ? m : m = a() && "xr" in navigator && G(); } s.isVisionOS = w; let b; const v = ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"]; function T() { return b !== void 0 ? b : b = v.includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; } s.isiOS = T; let k; function E() { return k !== void 0 || (k = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)), k; } s.isSafari = E; let I; function j() { return I !== void 0 ? I : I = navigator.userAgent.includes("OculusBrowser"); } s.isQuest = j; let B; function G() { return B !== void 0 || (B = document.createElement("a").relList.supports("ar")), B; } s.supportsQuickLookAR = G; async function X() { try { return (await navigator.permissions.query({ name: "microphone" })).state !== "denied"; } catch (J) { return console.error("Error querying `microphone` permissions.", J), !1; } } s.microphonePermissionsGranted = X; let O; function W() { if (O !== void 0) return O; const J = navigator.userAgent.match(/iPhone OS (\d+_\d+)/); if (J && (O = J[1].replace("_", ".")), !O) { const ke = navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/); ke && (O = ke[1]); } return O || (O = null), O; } s.getiOSVersion = W; let q; function se() { if (q !== void 0) return q; const J = navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/); return J ? q = J[1].replace("_", ".") : q = null, q; } s.getChromeVersion = se; let oe; function fe() { if (oe !== void 0) return oe; const J = navigator.userAgent.match(/Version\/(\d+\.\d+)/); return J && E() ? oe = J[1] : oe = null, oe; } s.getSafariVersion = fe; })(D || (D = {})); function hD() { return D.isDesktop(); } function dD() { return D.isMobileDevice(); } function uD() { return D.isiPad(); } function fD() { return D.isiPad(); } function pD() { return D.isAndroidDevice(); } function mD() { return D.isMozillaXR(); } function gD() { return D.isMacOS(); } function yD() { return D.isiOS(); } function _D() { return D.isSafari(); } function bD() { return D.isQuest(); } async function vD() { return D.microphonePermissionsGranted(); } const po = /* @__PURE__ */ new WeakMap(); function Bv(s, e, t) { if (!po.get(s)) { const n = new MutationObserver((o) => { d1(s, o); }); po.set(s, { observer: n, attributeChangedListeners: /* @__PURE__ */ new Map() }), n.observe(s, { attributes: !0 }); } const i = po.get(s).attributeChangedListeners; return i.has(e) || i.set(e, []), i.get(e).push(t), () => { Fv(s, e, t); }; } function Fv(s, e, t) { if (!po.get(s)) return; const i = po.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), po.get(s)?.observer.disconnect(), po.delete(s))); } function d1(s, e) { const t = po.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 i_ { reason; constructor(e) { this.reason = e; } } async function zv(s) { const e = await Promise.allSettled(s).catch((n) => [ new i_(n.message) ]); let t = !1; const i = e.map((n) => "value" in n ? n.value : (t = !0, new i_(n.reason))); return { anyFailed: t, results: i }; } const u1 = x("debugdebug"); let hg = !1; (x("noerrors") || x("nooverlaymessages")) && (hg = !0); const If = "needle_engine_global_error_container"; var Gi = /* @__PURE__ */ ((s) => (s[s.Log = 0] = "Log", s[s.Warn = 1] = "Warn", s[s.Error = 2] = "Error", s))(Gi || {}); function Uv() { return $v; } const Gp = new Array(); function f1(s) { Gp.push(s); } let Lf = !1; function p1(...s) { if (!Lf) { Lf = !0; try { for (let e = 0; e < Gp.length; e++) Gp[e](...s); } catch (e) { console.error(e); } Lf = !1; } } const Nv = console.error, m1 = function(...s) { Nv.apply(console, s), _1(s), mr(2, s, {}), y1(...s); }; function g1(s) { hg = !s, s ? console.error = m1 : console.error = Nv; } function wD(s) { return g1(s); } let $v = 0; function y1(...s) { $v += 1, p1(...s); } function _1(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 n_ = /* @__PURE__ */ new Set(); function mr(s, e, t = {}, i, n) { if (hg) 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 (n_.has(a)) return; n_.add(a); } const o = pe.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 || b1(s, r, e, t); } } const ba = /* @__PURE__ */ new Map(), s_ = 0.2; function b1(s, e, t, i = {}) { if (t == null) return; const n = w1(e); if (n.childElementCount >= 20) { const c = n.lastElementChild; o_(c); } t.length > 400 && (t = t.substring(0, 400) + "..."); const o = i.key ?? t; if (ba.has(o)) { ba.get(o)?.update(t, i); return; } const r = x1(s, t); n.prepend(r); const a = () => { ba.delete(o), o_(r); }; let l = setTimeout(a, Math.max(s_, i.duration ?? 10) * 1e3); ba.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(s_, h.duration) * 1e3)); }, removeFunction: a }); } function xD() { u1 && console.log("Clearing messages"); for (const s of ba.values()) s?.removeFunction.call(s); ba.clear(); } const v1 = ` @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 w1(s) { globalThis[If] || (globalThis[If] = /* @__PURE__ */ new Map()); const e = globalThis[If]; 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 = v1, t.appendChild(n), t; } } const Wv = /* @__PURE__ */ Symbol("logtype"), Dd = /* @__PURE__ */ new Map(); function o_(s) { s.remove(); const e = s[Wv], t = Dd.get(e) ?? []; t.push(s), Dd.set(e, t); } function x1(s, e) { if (Dd.has(s)) { const i = Dd.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[Wv] = 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; } class S1 { 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 C1) { 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 C1 = ["x", "y", "z", "w"], F = new S1(); class r_ { 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 Df { /** * 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 r_(this.alpha(this.minCutOff)), this.dx = new r_(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 Vv { 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 Df(e, t, i, n), this.y = new Df(e, t, i, n), this.z = new Df(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 cd = "needle:cameraController"; function P1(s) { return s[cd]; } function a_(s, e, t) { t ? s[cd] = e : s[cd] === e && (s[cd] = null); } const qp = "needle:autofit"; function k1(s) { return s[qp] === void 0 ? !0 : s[qp] !== !1; } function Xp(s, e) { s[qp] = e; } let rn; const O1 = { x: 0, y: 0, width: 0, height: 0 }, M1 = x("debugfocusrect"); function E1(s, e, t, i, n) { s instanceof Element && (M1 && s instanceof HTMLElement && (s.style.outline = "2px dashed rgba(255, 150, 0, .8)"), s = s.getBoundingClientRect()), rn = n.domElement.getBoundingClientRect(); const o = O1; o.x = s.x, o.y = s.y, o.width = s.width, o.height = s.height, o.x -= rn.x, o.y -= rn.y; const r = rn.width, a = rn.height, l = i.view, c = e.zoom; let h = l?.offsetX || 0, d = l?.offsetY || 0, f = rn.width, p = rn.height; f /= c, p /= c, h = f * (c - 1) * 0.5, d = p * (c - 1) * 0.5; const g = o.x + o.width * 0.5, y = o.y + o.height * 0.5, m = rn.width * 0.5, w = rn.height * 0.5, b = g - m, v = y - w; h -= b / c, d -= v / c, e.offsetX !== void 0 && (h += e.offsetX * (rn.width * 0.5)), e.offsetY !== void 0 && (d -= e.offsetY * (rn.height * 0.5)); const T = l?.offsetX || h, k = l?.offsetY || d; h = F.lerp(T, h, t), d = F.lerp(k, d, t); const E = l?.width || r, I = l?.height || a; f = F.lerp(E, f, t), p = F.lerp(I, p, t), i.setViewOffset(r, a, h, d, f, 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 SD(s, e, t) { const i = s.length(), n = e.length(), o = F.lerp(i, n, t); return s.lerp(e, t).normalize().multiplyScalar(o); } const jf = new V(), Hv = new V().setFromAxisAngle(new _(0, 1, 0), Math.PI); function CD(s, e) { s.lookAt(e), s.quaternion.multiply(Hv); } function Cu(s, e, t = !0, i = !1) { if (s === e) return; jf.copy(s.quaternion); const n = te(e), o = te(s); if (i) { if (Qn(s, ve(e)), t) { const r = o.y, a = o.sub(F1(s)); a.y = r, s.lookAt(a), s.quaternion.multiply(Hv); } Number.isNaN(s.quaternion.x) && s.quaternion.copy(jf); return; } t && (n.y = o.y), s.lookAt(n), Number.isNaN(s.quaternion.x) && s.quaternion.copy(jf); } function PD(s, e, t, i = 1) { if (t) { const n = U(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 R1 = new Yi(() => new _(), 100); function U(s, e, t) { const i = R1.get(); return i.set(0, 0, 0), s instanceof _ ? 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 T1 = new Yi(() => new re(), 30); function A1(s) { const e = T1.get(); return s ? e.copy(s) : e.set(0, 0, 0), e; } const I1 = new Yi(() => new V(), 100); function bi(s, e, t, i) { const n = I1.get(); return n.identity(), s instanceof V ? 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 dg = new Yi(() => new _(), 100), l_ = /* @__PURE__ */ Symbol("lastMatrixWorldUpdateKey"); function te(s, e = null, t = !0) { const i = e ?? dg.get(); return s ? s.parent ? (t && s.updateWorldMatrix(!0, !1), s.matrixWorldNeedsUpdate && s[l_] !== Date.now() && (s[l_] = Date.now(), s.updateMatrixWorld()), i.setFromMatrixPosition(s.matrixWorld), i) : i.copy(s.position) : i.set(0, 0, 0); } function Et(s, e) { if (!s) return s; const t = dg.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 Wa(s, e, t, i) { const n = dg.get(); return n.set(e, t, i), Et(s, n), s; } const jd = new Yi(() => new V(), 100), br = new V(), Bf = new V(); function ve(s, e = null) { if (!s) return jd.get().identity(); const t = e ?? jd.get(); return s.parent ? (s.getWorldQuaternion(t), t) : t.copy(s.quaternion); } function Qn(s, e) { if (!s) return; e !== br && br.copy(e); const t = br; s?.parent?.getWorldQuaternion(Bf), Bf.invert(); const n = Bf.multiply(t); s.quaternion.set(n.x, n.y, n.z, n.w); } function Gv(s, e, t, i, n) { br.set(e, t, i, n), Qn(s, br); } const L1 = new Yi(() => new _(), 100), D1 = new _(); function Xe(s, e = null) { return e || (e = L1.get()), s ? s.parent ? (s.getWorldScale(e), e) : e.copy(s.scale) : e.set(0, 0, 0); } function Rc(s, e) { if (!s) return; if (!s.parent) { s.scale.copy(e); return; } const t = D1; s.parent.getWorldScale(t), s.scale.copy(e), s.scale.divide(t); } const j1 = new _(), c_ = new V(); function kD(s) { return ve(s, c_), j1.set(0, 0, 1).applyQuaternion(c_); } const B1 = new Yi(() => new _(), 100), h_ = new V(); function F1(s, e) { return e || (e = B1.get().set(0, 0, 1)), ve(s, h_), e.applyQuaternion(h_); } const d_ = new ct(), u_ = new ct(), z1 = new _(); function qv(s) { const e = jd.get(); return s.getWorldQuaternion(e), u_.setFromQuaternion(e), u_; } function Xv(s, e) { const t = jd.get(); Qn(s, t.setFromEuler(e)); } function ug(s) { const e = qv(s), t = z1; return t.set(e.x, e.y, e.z), t.x = F.toDegrees(t.x), t.y = F.toDegrees(t.y), t.z = F.toDegrees(t.z), t; } function U1(s, e) { Pu(s, e.x, e.y, e.z, !0); } function Pu(s, e, t, i, n = !0) { n && (e = F.toRadians(e), t = F.toRadians(t), i = F.toRadians(i)), d_.set(e, t, i), br.setFromEuler(d_), Qn(s, br); } function Qp(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 OD(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 N1(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 Bd extends qn { static vertex = ` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.0); }`; constructor() { super({ vertexShader: Bd.vertex, uniforms: { map: new Hi(null), flipY: new Hi(!0), writeDepth: new Hi(!1), depthTexture: new Hi(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 Er { static planeGeometry = new Cn(2, 2, 1, 1); static renderer = new Fr({ antialias: !1, alpha: !0 }); static perspectiveCam = new de(); static orthographicCam = new fu(); static scene = new Xi(); static blitMaterial = new Bd(); static mesh = new H(Er.planeGeometry, Er.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 = Bd.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 xe(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 Hi(!0), o.uniforms.depthTexture.value = a) : (o.uniforms.writeDepth = new Hi(!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(), f = n.getContext(); l ? f.enable(f.DEPTH_TEST) : f.disable(f.DEPTH_TEST), n.state.buffers.depth.setMask(c), n.setClearColor(new re(0, 0, 0), 0), n.pixelRatio !== window.devicePixelRatio && n.xr.isPresenting === !1 && n.setPixelRatio(window.devicePixelRatio), n.setRenderTarget(t), n.clear(), n.render(this.scene, this.perspectiveCam), n.setRenderTarget(d), f.enable(f.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 = $1(e)); const i = e.image; if (W1(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 $1(s) { return Er.copyTexture(s); } function MD(s, e = !1) { return Er.textureToCanvas(s, e); } function W1(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 V1(s) { const e = s.type; return e === "Mesh" || e === "SkinnedMesh"; } function Qv(s, e) { e ? s["needle:rendercustomshadow"] = !0 : s["needle:rendercustomshadow"] = !1; } function H1(s) { if (s) { if (s["needle:rendercustomshadow"] === !0) return !0; if (s["needle:rendercustomshadow"] == null) return !0; } return !1; } function Mi(s, e = void 0, t = void 0, i = void 0) { const n = i || new zt(); n.makeEmpty(); const o = []; function r(l) { let c = !0; if (l.visible && k1(l) !== !1 && !(l.type === "TransformControlsGizmo" || l.type === "TransformControlsPlane")) { if (l instanceof oS && (c = !1), l instanceof pv && (c = !1), l instanceof $a && (c = !1), l.isGizmo === !0 && (c = !1), l.material instanceof fv && (c = !1), V1(l) || (c = !1), t && l.layers.test(t) === !1 && (c = !1), c) { if (e && Array.isArray(e) && e?.includes(l)) return; if (typeof e == "function" && e(l) === !0) return; } if (l.isUI !== !0) { if (c) { const h = l.children; l.children = o; const d = l.position, f = 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, f); 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 G1(s, e, t) { const i = Mi([s], t?.ignore), n = new _(); i.getSize(n); const o = new _(); i.getCenter(o); const r = new _(); e.getSize(r); const a = new _(); e.getCenter(a); const l = new _(); 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 && Rc(s, Xe(s).multiplyScalar(c)), t?.position !== !1) { const d = new _(); i.getCenter(d), d.y = i.min.y; const f = new _(); e.getCenter(f), f.y = e.min.y; const p = f.clone().sub(d); h && p.multiplyScalar(c), Et(s, te(s).add(p)); } return { boundsBefore: i, scale: l }; } function q1(s, e) { const t = Mi([s]), i = new _(); t.getCenter(i), i.y = t.min.y; const n = e.clone().sub(i), o = te(s); return Et(s, o.add(n)), { offset: n, bounds: t }; } function Yv(s, e, t, i) { if (Array.isArray(e)) { let r = !0; for (let a = 0; a < e.length; a++) Yv(s, e[a], a, e) || (r = !1); return r; } if (e.type === "MeshStandardMaterial" || e.type === "MeshBasicMaterial") return !1; if (e["material:fbx"] != null) return !0; const n = new pt(); n["material:fbx"] = e; const o = e; return o && (o.map ? n.color.set(1, 1, 1) : n.color.copyLinearToSRGB(o.color), n.emissive.copyLinearToSRGB(o.emissive), n.emissiveIntensity = o.emissiveIntensity, n.opacity = o.opacity, n.displacementScale = o.displacementScale, n.transparent = o.transparent, n.bumpMap = o.bumpMap, n.aoMap = o.aoMap, n.map = o.map, n.displacementMap = o.displacementMap, n.emissiveMap = o.emissiveMap, n.normalMap = o.normalMap, n.envMap = o.envMap, n.alphaMap = o.alphaMap, n.metalness = o.reflectivity, n.vertexColors = o.vertexColors, o.shininess && (n.roughness = 1 - Math.sqrt(o.shininess) / 10), n.needsUpdate = !0), t === void 0 ? s.material = n : i[t] = n, !0; } let Oh = !1; f1((...s) => { L() && pe.Current?.isInXR && (hc(!0), Kv("error", ...s)); }); function hc(s) { if (s) { if (Oh) return; Oh = !0, Q1(); } else { if (!Oh) return; Oh = !1, Y1(); } } const dc = { log: void 0, warn: void 0,