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,400 lines (1,392 loc) • 1.75 MB
var Rx = Object.defineProperty; var kx = (s, t, e) => t in s ? Rx(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e; var r = (s, t, e) => (kx(s, typeof t != "symbol" ? t + "" : t, e), e), Cf = (s, t, e) => { if (!t.has(s)) throw TypeError("Cannot " + e); }; var fe = (s, t, e) => (Cf(s, t, "read from private field"), e ? e.call(s) : t.get(s)), zi = (s, t, e) => { if (t.has(s)) throw TypeError("Cannot add the same private member more than once"); t instanceof WeakSet ? t.add(s) : t.set(s, e); }, ln = (s, t, e, i) => (Cf(s, t, "write to private field"), i ? i.call(s, e) : t.set(s, e), e); var Pl = (s, t, e) => (Cf(s, t, "access private method"), e); import { Vector2 as oe, Vector3 as v, Vector4 as ge, Quaternion as W, PlaneGeometry as qn, PerspectiveCamera as be, Scene as Mi, ShaderMaterial as bn, Uniform$1 as ho, Mesh as q, WebGLRenderer as kr, Texture as Fe, Euler as jt, Box3 as Pi, MeshStandardMaterial as It, Color as ce, ShadowMaterial as Kb, Box3Helper as Zb, GridHelper as ig, Material as Se, Matrix3 as Jb, Matrix4 as se, Layers as wo, Object3D as L, Ray as xo, MathUtils as Ss, AxesHelper as Oi, MeshBasicMaterial as Me, DoubleSide as Ri, BufferGeometry as Cs, Group as uo, SphereGeometry as vu, BoxGeometry as Da, SpriteMaterial as Tx, Sprite as Ax, Shape as Ex, ExtrudeGeometry as Ix, Fog as e0, DirectionalLight as Yp, PointLight as ng, Line as Ec, BufferAttribute as mt, CylinderGeometry as Dx, EdgesGeometry as Lx, LineSegments as t0, LineBasicMaterial as i0, Sphere as wu, Plane as wr, Raycaster as xu, ArrayCamera as jx, SkinnedMesh as Ps, InterleavedBufferAttribute as n0, Skeleton as Bx, Bone as Fx, Source as zx, WebGLCubeRenderTarget as Ux, CubeCamera as Nx, AnimationClip as fo, TextureLoader as wa, PropertyBinding as La, LinearSRGBColorSpace as Rs, ShaderChunk as Jt, UniformsLib as $x, FileLoader as s0, DataTexture as sg, RGBAFormat as Su, EquirectangularReflectionMapping as Os, SRGBColorSpace as ks, Clock as Wx, NoToneMapping as ja, PCFSoftShadowMap$1 as Vx, BasicNodeLibrary as Hx, WebGLRenderTarget as Ts, DepthTexture as Gx, NearestFilter as Id, LoopRepeat as qx, LoopOnce as Kp, AnimationMixer as og, CompressedTexture as Xx, FrontSide as So, Frustum as D_, OrthographicCamera as rg, AudioListener as Qx, PositionalAudio as Yx, AudioLoader as Zp, EventDispatcher as ag, BackSide as Cu, MeshDepthMaterial as Kx, CustomBlending as Zx, MaxEquation as Jx, AmbientLight as e1, HemisphereLight as t1, InvertStencilOp as i1, DecrementWrapStencilOp as n1, IncrementWrapStencilOp as s1, DecrementStencilOp as o1, IncrementStencilOp as r1, ReplaceStencilOp as a1, ZeroStencilOp as l1, KeepStencilOp as c1, AlwaysStencilFunc as h1, GreaterEqualStencilFunc as d1, NotEqualStencilFunc as u1, GreaterStencilFunc as f1, LessEqualStencilFunc as p1, EqualStencilFunc as m1, LessStencilFunc as g1, NeverStencilFunc as L_, RawShaderMaterial as o0, GLSL3 as _1, AlwaysDepth as y1, GreaterEqualDepth as b1, GreaterDepth as v1, LessEqualDepth as w1, LessDepth as x1, NotEqualDepth as S1, EqualDepth as C1, BatchedMesh as j_, MeshPhysicalMaterial as Jp, UnsignedByteType as P1, LinearFilter as B_, RingGeometry as O1, Line3 as M1, AdditiveBlending as r0, BoxHelper as R1, SpotLight as k1, DirectionalLightHelper as T1, CameraHelper as A1, LOD as E1, Triangle as I1, NormalBlending as D1, NeutralToneMapping as Ic, AgXToneMapping as Pu, ACESFilmicToneMapping as lg, ReinhardToneMapping as cg, LinearToneMapping as Ou, HalfFloatType as L1, VideoTexture as j1, CubeTexture as B1, CompressedCubeTexture as F1, EquirectangularRefractionMapping as z1, VectorKeyframeTrack as U1, QuaternionKeyframeTrack as N1, Audio as $1, MirroredRepeatWrapping as F_, UniformsUtils as a0, ShaderLib as Dd, MeshNormalMaterial as W1, AudioContext as V1, PMREMGenerator$1 as H1 } from "./three.js"; import { createLoaders as hg, getRaycastMesh as l0, LODsManager as Hr, NEEDLE_progressive as Ze, addDracoAndKTX2Loaders as G1, configureLoader as q1, setDracoDecoderLocation as X1, setKTX2TranscoderLocation as Q1 } from "./gltf-progressive.js"; import { GroundedSkybox as Ba, Font as Y1, TextGeometry as K1, FontLoader as Z1, GLTFLoader as xr, TransformControlsGizmo as c0, EXRLoader as Ld, RGBELoader as em, Stats as J1, nodeFrame as eS, OrbitControls as h0, PositionalAudioHelper as tS, HorizontalBlurShader as iS, VerticalBlurShader as nS, GLTFExporter as d0, strToU8 as u0, zipSync as sS, XRControllerModelFactory as oS, XRHandMeshModel as rS, Line2 as aS, LineGeometry as lS, LineMaterial as cS, KTX2Loader as hS, TransformControls as dS, InteractiveGroup as uS, HTMLMesh as fS, VertexNormalsHelper as pS, OBJLoader as dg, FBXLoader as f0, mergeVertices as mS } from "./three-examples.js"; import { fetchProfile as gS, MotionController as _S, $70d766613f57b014$export$2e2bcd8739ae039 as z_, ByteBuffer as yS, v5 as U_, md5 as N_, SIZE_PREFIX_LENGTH as p0, Builder as ug, createNoise4D as bS, Matrix4 as Pf, BatchedParticleRenderer as vS, ParticleSystem as wS, RenderMode as us, TrailParticle as $_, ConstantColor as xS, Vector4 as SS, ConstantValue as CS, WorkerBase as PS, WorkerWrapper as OS, MeshBVH as MS } from "./vendor.js"; import { __webpack_exports__default as Te, __webpack_exports__Text as m0, __webpack_exports__Block as g0, __webpack_exports__update as RS, SimpleStateBehavior as kS, __webpack_exports__Inline as Of, __webpack_exports__FontLibrary as W_, ThreeMeshUI as V_ } from "./three-mesh-ui.js"; let _0, H_ = null; function Vn() { return _0; } function y0(s) { if (s == null) { console.warn("Oh no: someone tried registering a non-existend gltf-loader. When you see this log it might mean that needle-engine is being imported multiple times. Please check your project setup."); return; } H_ !== s && (H_ = s, _0 = new s()); } const Mf = /* @__PURE__ */ new Map(); function ui(s = ((t) => (t = globalThis.location) == null ? void 0 : t.hostname)()) { if (Mf.has(s)) return Mf.get(s); const e = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s); return Mf.set(s, e), e === !0; } function TS() { return window.location.hostname.includes("glitch.me"); } const G_ = typeof window !== void 0 ? window.location.search.includes("debugcontext") : !1; var me = /* @__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))(me || {}); class pe { /** The currently active (rendering) Needle Engine context */ static get Current() { return globalThis["NeedleEngine.Context.Current"]; } /** @internal */ static set Current(t) { globalThis["NeedleEngine.Context.Current"] = t; } /** Returns the array of all registered Needle Engine contexts. Do not modify */ static get All() { return this.Registered; } /** @internal Internal use only */ static register(t) { this.Registered.indexOf(t) === -1 && (G_ && console.warn("Registering context"), this.Registered.push(t), this.dispatchCallback("ContextRegistered", t)); } /** @internal Internal use only */ static unregister(t) { const e = this.Registered.indexOf(t); e !== -1 && (G_ && console.warn("Unregistering context"), this.Registered.splice(e, 1)); } /** * Register a callback to be called when the given event occurs */ static registerCallback(t, e) { this._callbacks[t] || (this._callbacks[t] = []), this._callbacks[t].push(e); } /** Unregister a callback */ static unregisterCallback(t, e) { if (!this._callbacks[t]) return; const i = this._callbacks[t].indexOf(e); i !== -1 && this._callbacks[t].splice(i, 1); } /** @internal */ static dispatchCallback(t, e, i) { if (!this._callbacks[t]) return !0; const n = { event: t, context: e }; if (i) for (const a in i) n[a] = i[a]; const o = new Array(); return this._callbacks[t].forEach((a) => { const l = a(n); l instanceof Promise && o.push(l); }), Promise.all(o); } /** * Register a callback to be called when a context is created */ static addContextCreatedCallback(t) { this.registerCallback("ContextCreated", t); } /** * Register a callback to be called when a context is registered */ static addContextDestroyedCallback(t) { this.registerCallback("ContextDestroyed", t); } } /** All currently registered Needle Engine contexts. Do not modify */ r(pe, "Registered", []), r(pe, "_callbacks", {}); const AS = () => (s) => s; function WI(s) { return AS()(s); } function VI() { return !!x("debug"); } class tn { constructor(t, e) { r(this, "_factory"); r(this, "_cache", []); r(this, "_maxSize"); r(this, "_index", 0); this._factory = t, this._maxSize = e; } get() { const t = this._index % this._maxSize; return this._index++, this._cache.length <= t && (this._cache[t] = this._factory()), this._cache[t]; } } let Qo = !1; const tm = new Array(); typeof window < "u" && setTimeout(() => { if (Qo) { const s = {}, t = new URL(window.location.href), e = new URL(t); e.searchParams.append("console", ""); const i = e.toString().replace(/=$|=(?=&)/g, ""); for (const o of tm) { const a = new URL(t); a.searchParams.append(o, ""), s[o] = a.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 = Qo === !0 ? "" : ` (containing "${Qo}")`; console.group("Available URL parameters:" + n); for (const o of Object.keys(s).sort()) typeof Qo == "string" && !o.toLowerCase().includes(Qo.toLowerCase()) || (console.groupCollapsed(o), console.log("Reload with this flag enabled:"), console.log(s[o]), console.groupEnd()); console.groupEnd(); } }, 100); function Mu() { var s; return new URLSearchParams((s = globalThis.location) == null ? void 0 : s.search); } function x(s) { Qo && !tm.includes(s) && tm.push(s); const t = Mu(); if (t.has(s)) { const e = t.get(s); if (e) { const i = Number(e); return isNaN(i) ? e : i; } else return !0; } return !1; } Qo = x("help"); function HI(s, t) { const e = Mu(); e.has(s) ? e.set(s, t) : e.append(s, t), document.location.search = e.toString(); } function jd(s, t, e = !0) { const i = Mu(); i.has(s) ? t === null ? i.delete(s) : i.set(s, t) : t !== null && i.append(s, t), e ? ES(s, i) : b0(s, i); } function q_(s, t, e) { s.has(t) ? s.set(t, e.toString()) : s.append(t, e.toString()); } function ES(s, t, e) { window.history.pushState(e, s, "?" + t.toString()); } function b0(s, t, e) { window.history.replaceState(e, s, "?" + t.toString()); } function GI(s) { for (var t = "", e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", i = e.length, n = 0; n < s; n++) t += e.charAt(Math.floor(Math.random() * i)); return t; } function qI(s, t) { return Math.floor(Math.random() * (t - 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 IS() { const s = X_[Math.floor(Math.random() * X_.length)], t = Q_[Math.floor(Math.random() * Q_.length)]; return s + "_" + t; } function DS(s) { return s = s.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, ""), s.trim(); } function Dc(s, t, e = !0, i = !1) { var n; if (t == null) return null; if (t.userData && t.userData.guid === s) return t; if (t.guid == s) return t; if (i && (n = t.userData) != null && n.components) { for (const o of t.userData.components) if (o.guid === s) return o; } if (e) { if (t.scenes) for (const o in t.scenes) { const a = t.scenes[o], l = Dc(s, a, e, i); if (l) return l; } if (t.children) for (const o in t.children) { const a = t.children[o], l = Dc(s, a, e, i); if (l) return l; } } } function Ru(s, t) { if (s != null && typeof s == "object") { let e; Array.isArray(s) ? e = [] : (e = Object.create(s), Object.assign(e, s)); for (const i of Object.keys(s)) { const n = s[i]; t && !t(s, i, n) ? e[i] = n : (n == null ? void 0 : n.clone) !== void 0 && typeof n.clone == "function" ? e[i] = n.clone() : e[i] = Ru(n, t); } return e; } return s; } function Hn(s) { return new Promise((t, e) => { setTimeout(t, s); }); } function ku(s, t) { if (s <= 0) return Promise.resolve(); if (t || (t = pe.Current), !t) return Promise.reject("No context"); const e = t.time.frameCount + s; return new Promise((i, n) => { if (!t) return n("No context"); const o = () => { t.time.frameCount >= e && (t.pre_update_callbacks.splice(t.pre_update_callbacks.indexOf(o), 1), i()); }; t.pre_update_callbacks.push(o); }); } const Rh = x("debugresolveurl"), LS = "rel:"; function XI(s, t) { return Tr(s, t); } function Tr(s, t) { if (t === void 0) return Rh && console.warn("getPath: uri is undefined, returning uri", t), t; if (t.startsWith("./")) return t; if (t.startsWith("http")) return Rh && console.warn("getPath: uri is absolute, returning uri", t), t; if (s === void 0) return Rh && console.warn("getPath: source is undefined, returning uri", t), t; t.startsWith(LS) && (t = t.substring(4)); const e = s.lastIndexOf("/"); if (e >= 0) { const i = s.substring(0, e + 1); for (; i.endsWith("/") && t.startsWith("/"); ) t = t.substring(1); const n = i + t; return Rh && console.log("source:", s, `changed uri from`, t, ` to `, n, ` basePath: ` + i), n; } return t; } class jS { constructor(t, e) { r(this, "writeCallbacks", []); r(this, "_applied", !1); r(this, "_object"); r(this, "_prop"); r(this, "_wrapperProp"); this._object = t, this._prop = e, this._wrapperProp = Symbol("$" + e), this.apply(); } subscribeWrite(t) { this.writeCallbacks.push(t); } unsubscribeWrite(t) { const e = this.writeCallbacks.indexOf(t); e !== -1 && this.writeCallbacks.splice(e, 1); } apply() { if (this._applied || !this._object) return; const t = this._object, e = this._prop; if (t[e] === void 0) return; this._applied = !0, t[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 = t[e]; t[this._wrapperProp] = i, Object.defineProperty(t, e, { get: () => t[this._wrapperProp], set: (a) => { t[this._wrapperProp] = a; for (const l of this.writeCallbacks) l(a, this._prop); } }); } revoke() { if (!this._applied || !this._object) return; this._applied = !1; const t = this._object, e = this._prop; Reflect.deleteProperty(t, e); const i = t[this._wrapperProp]; t[e] = i, Reflect.deleteProperty(t, this._wrapperProp); } dispose() { this.revoke(), this.writeCallbacks.length = 0, this._object = null; } } class po { constructor(t, e) { r(this, "_watches", []); if (Array.isArray(e)) for (const i of e) this._watches.push(new po(t, i)); else this._watches.push(new jS(t, e)); } subscribeWrite(t) { for (const e of this._watches) e.subscribeWrite(t); } unsubscribeWrite(t) { for (const e of this._watches) e.unsubscribeWrite(t); } apply() { for (const t of this._watches) t.apply(); } revoke() { for (const t of this._watches) t.revoke(); } dispose() { for (const t of this._watches) t.dispose(); this._watches.length = 0; } } const na = Symbol("needle:watches"); function fg(s, t) { if (!s[na]) if (s instanceof oe) s[na] = new po(s, ["x", "y"]); else if (s instanceof v) s[na] = new po(s, ["x", "y", "z"]); else if (s instanceof ge || s instanceof W) s[na] = new po(s, ["x", "y", "z", "w"]); else return !1; return s[na].subscribeWrite(t), !0; } function v0(s, t) { if (!s) return; const e = s[na]; e && e.unsubscribeWrite(t); } var X; ((s) => { let t; function e() { if (t !== void 0) return t; const j = window.navigator.userAgent, H = /Windows|MacOS|Mac OS/.test(j), Y = /Windows NT/.test(j) && /Edg/.test(j) && !/Win64/.test(j); return t = H && !Y && !w(); } s.isDesktop = e; 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 l(); } s.isIPad = o; let a; function l() { return a !== void 0 ? a : a = /iPad/.test(navigator.userAgent); } s.isiPad = l; let c; function h() { return c !== void 0 ? c : c = /Android/.test(navigator.userAgent); } s.isAndroidDevice = h; let d; function u() { return d !== void 0 ? d : d = /WebXRViewer\//i.test(navigator.userAgent); } s.isMozillaXR = u; let p; function m() { if (p !== void 0) return p; if (navigator.userAgentData) return p = navigator.userAgentData.platform === "macOS"; { const j = navigator.userAgent.toLowerCase(); return p = j.includes("mac os x") || j.includes("macintosh"); } } s.isMacOS = m; let g; function _() { return g !== void 0 ? g : g = m() && "xr" in navigator; } s.isVisionOS = _; let y; const b = ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"]; function w() { return y !== void 0 ? y : y = b.includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; } s.isiOS = w; let P; function k() { return P !== void 0 || (P = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)), P; } s.isSafari = k; let O; function M() { return O !== void 0 ? O : O = navigator.userAgent.includes("OculusBrowser"); } s.isQuest = M; let E; function B() { return E !== void 0 || (E = document.createElement("a").relList.supports("ar")), E; } s.supportsQuickLookAR = B; async function A() { try { return (await navigator.permissions.query({ name: "microphone" })).state !== "denied"; } catch (j) { return console.error("Error querying `microphone` permissions.", j), !1; } } s.microphonePermissionsGranted = A; let F; function U() { if (F !== void 0) return F; const j = navigator.userAgent.match(/iPhone OS (\d+_\d+)/); if (j && (F = j[1].replace("_", ".")), !F) { const H = navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/); H && (F = H[1]); } return F || (F = null), F; } s.getiOSVersion = U; let Z; function T() { if (Z !== void 0) return Z; const j = navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/); return j ? Z = j[1].replace("_", ".") : Z = null, Z; } s.getChromeVersion = T; })(X || (X = {})); function QI() { return X.isDesktop(); } function YI() { return X.isMobileDevice(); } function KI() { return X.isiPad(); } function ZI() { return X.isiPad(); } function JI() { return X.isAndroidDevice(); } function eD() { return X.isMozillaXR(); } function tD() { return X.isMacOS(); } function iD() { return X.isiOS(); } function nD() { return X.isSafari(); } function sD() { return X.isQuest(); } async function oD() { return X.microphonePermissionsGranted(); } const BS = /ip=(?<ip>.+?)\n/s; async function rD() { const t = await (await fetch("https://www.cloudflare.com/cdn-cgi/trace")).text(), e = BS.exec(t); return e ? e[1] : null; } async function aD() { const s = await fetch("https://api.db-ip.com/v2/free/self").catch(() => null); return s ? (await s.json()).ipAddress : void 0; } async function lD() { const s = await fetch("https://api.db-ip.com/v2/free/self").catch(() => null); return s ? await s.json() : void 0; } const ro = /* @__PURE__ */ new WeakMap(); function FS(s, t, e) { if (!ro.get(s)) { const n = new MutationObserver((o) => { US(s, o); }); ro.set(s, { observer: n, attributeChangedListeners: /* @__PURE__ */ new Map() }), n.observe(s, { attributes: !0 }); } const i = ro.get(s).attributeChangedListeners; i.has(t) || i.set(t, []), i.get(t).push(e); } function zS(s, t, e) { if (!ro.get(s)) return; const i = ro.get(s).attributeChangedListeners; if (!i.has(t)) return; const n = i.get(t), o = n.indexOf(e); if (o !== -1 && (n.splice(o, 1), n.length <= 0)) { i.delete(t); const a = ro.get(s); a == null || a.observer.disconnect(), ro.delete(s); } } function US(s, t) { const e = ro.get(s).attributeChangedListeners; for (const i of t) if (i.type === "attributes") { const n = i.attributeName, o = s.getAttribute(n); if (e.has(n)) for (const a of e.get(n)) a(o); } } class Y_ { constructor(t) { r(this, "reason"); this.reason = t; } } async function w0(s) { const t = await Promise.allSettled(s).catch((n) => [ new Y_(n.message) ]); let e = !1; const i = t.map((n) => "value" in n ? n.value : (e = !0, new Y_(n.reason))); return { anyFailed: e, results: i }; } async function NS(s) { if (!globalThis.QRCode) { const i = "https://cdn.rawgit.com/davidshimjs/qrcodejs/gh-pages/qrcode.min.js"; let n = document.head.querySelector(`script[src="${i}"]`); n || (n = document.createElement("script"), n.src = i, document.head.appendChild(n)), await new Promise((o, a) => { n.addEventListener("load", () => { o(!0); }); }); } const t = globalThis.QRCode, e = s.domElement ?? document.createElement("div"); return new t(e, { width: s.width ?? 256, height: s.height ?? 256, colorDark: "#000000", colorLight: "#ffffff", correctLevel: t.CorrectLevel.M, ...s }), e; } const x0 = x("debugdebug"); let Lc = !1; (x("noerrors") || x("nooverlaymessages")) && (Lc = !0); const Rf = "needle_engine_global_error_container"; var Zi = /* @__PURE__ */ ((s) => (s[s.Log = 0] = "Log", s[s.Warn = 1] = "Warn", s[s.Error = 2] = "Error", s))(Zi || {}); function pg() { return P0; } const im = new Array(); function $S(s) { im.push(s); } let kf = !1; function WS(...s) { if (!kf) { kf = !0; try { for (let t = 0; t < im.length; t++) im[t](...s); } catch (t) { console.error(t); } kf = !1; } } const S0 = console.error, C0 = function(...s) { S0.apply(console, s), GS(s), jn(2, s), nm(...s); }; function VS(s) { Lc = !s, s ? console.error = C0 : console.error = S0; } function cD(s) { return VS(s); } function HS() { Lc || (x0 && console.warn("Patch console", window.location.hostname), console.error = C0, window.addEventListener("error", (s) => { if (!s) return; const t = s.error; if (t === void 0) { ui() && console.warn("Received unknown error", s, s.target); return; } jn(2, t, s.filename, s.lineno), nm(s); }, !0), window.addEventListener("unhandledrejection", (s) => { Lc || s && (s.reason ? jn(2, s.reason.message, s.reason.stack) : jn(2, "unhandled rejection"), nm(s)); })); } let P0 = 0; function nm(...s) { P0 += 1, WS(...s); } function GS(s) { if (Array.isArray(s)) for (let t = 0; t < s.length; t++) { const e = s[t]; typeof e == "string" && e.startsWith("THREE.PropertyBinding: Trying to update node for track:") && (s[t] = "Some animated objects couldn't be found: see console for details"); } } function jn(s, t, e, i) { if (Lc) return; const n = pe.Current, o = (n == null ? void 0 : n.domElement) ?? document.querySelector("needle-engine"); if (o) { if (Array.isArray(t)) { let a = ""; for (let l = 0; l < t.length; l++) { let c = t[l]; c instanceof Error && (c = c.message), typeof c != "object" && (l > 0 && (a += " "), a += c); } t = a; } !t || t.length <= 0 || qS(s, o, t); } } const ac = /* @__PURE__ */ new Map(); function qS(s, t, e) { if (e == null) return; const i = QS(t); if (i.childElementCount >= 20) { const l = i.lastElementChild; K_(l); } e.length > 400 && (e = e.substring(0, 400) + "..."); const n = e; if (ac.has(n)) return; const o = YS(s, e); i.prepend(o); const a = () => { ac.delete(n), K_(o); }; ac.set(n, a), setTimeout(a, 1e4); } function hD() { x0 && console.log("Clearing messages"); for (const s of ac.values()) s == null || s.call(s); ac.clear(); } const XS = ` @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 QS(s) { globalThis[Rf] || (globalThis[Rf] = /* @__PURE__ */ new Map()); const t = globalThis[Rf]; if (t.has(s)) return t.get(s); { const e = document.createElement("div"); t.set(s, e), e.setAttribute("data-needle_engine_debug_overlay", ""), e.classList.add("debug-container"), e.style.cssText = ` position: absolute; top: 0; right: 5px; padding-top: 0px; max-width: 70%; max-height: calc(100% - 5px); z-index: 9999999999; pointer-events: scroll; display: flex; align-items: end; flex-direction: column; color: white; overflow: auto; word-break: break-word; `, s.shadowRoot ? s.shadowRoot.appendChild(e) : s.appendChild(e); const i = document.createElement("style"); return i.innerHTML = XS, e.appendChild(i), e; } } const O0 = Symbol("logtype"), Bd = /* @__PURE__ */ new Map(); function K_(s) { s.remove(); const t = s[O0], e = Bd.get(t) ?? []; e.push(s), Bd.set(t, e); } function YS(s, t) { if (Bd.has(s)) { const i = Bd.get(s); if (i.length > 0) { const n = i.pop(); return n.innerHTML = t, n; } } const e = document.createElement("div"); switch (e.setAttribute("data-id", "__needle_engine_debug_overlay"), e.style.marginRight = "5px", e.style.padding = ".5em", e.style.backgroundColor = "rgba(0,0,0,.9)", e.style.marginTop = "5px", e.style.marginBottom = "3px", e.style.borderRadius = "8px", e.style.pointerEvents = "all", e.style.userSelect = "text", e.style.maxWidth = "250px", e.style.whiteSpace = "pre-wrap", e.style["backdrop-filter"] = "blur(10px)", e.style["-webkit-backdrop-filter"] = "blur(10px)", e.style.backgroundColor = "rgba(20,20,20,.8)", e.style.boxShadow = "inset 0 0 80px rgba(0,0,0,.2), 0 0 5px rgba(0,0,0,.2)", e.style.border = "1px solid rgba(160,160,160,.2)", e[O0] = s, s) { case 0: e.classList.add("log"), e.style.color = "rgba(200,200,200,.7)", e.style.backgroundColor = "rgba(40,40,40,.7)"; break; case 1: e.classList.add("warn"), e.style.color = "rgb(255, 255, 150)", e.style.backgroundColor = "rgba(50,50,20,.8)"; break; case 2: e.classList.add("error"), e.style.color = "rgb(255, 50, 50", e.style.backgroundColor = "rgba(50,20,20,.8)"; break; } return e.title = "Open the browser console (F12) for more information", e.innerHTML = t, e; } class KS { constructor() { r(this, "Rad2Deg", 180 / Math.PI); r(this, "Deg2Rad", Math.PI / 180); r(this, "Epsilon", 1e-5); } random(t, e) { return Array.isArray(t) ? t.length <= 0 ? null : t[Math.floor(Math.random() * t.length)] : t !== void 0 && e !== void 0 ? Math.random() * (e - t) + t : Math.random(); } randomVector3(t, e = 0, i = 1) { t.x = this.random(e, i), t.y = this.random(e, i), t.z = this.random(e, i); } clamp(t, e, i) { return t < e ? e : t > i ? i : t; } clamp01(t) { return this.clamp(t, 0, 1); } /** * Linear interpolate */ lerp(t, e, i) { return i = i < 0 ? 0 : i, i = i > 1 ? 1 : i, t + (e - t) * i; } /** * */ inverseLerp(t, e, i) { return (i - t) / (e - t); } /** * 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(t, e, i, n, o) { return n + (o - n) * (t - e) / (i - e); } moveTowards(t, e, i) { return t += i, (i < 0 && t < e || i > 0 && t > e) && (t = e), t; } /** * Converts radians to degrees */ toDegrees(t) { return t * 180 / Math.PI; } /** * Converts degrees to radians */ toRadians(t) { return t * Math.PI / 180; } tan(t) { return Math.tan(t); } gammaToLinear(t) { return Math.pow(t, 2.2); } linearToGamma(t) { return Math.pow(t, 1 / 2.2); } approximately(t, e, i = Number.EPSILON) { for (const n of ZS) { const o = t[n], a = e[n]; if (o === void 0 || a === void 0) break; if (Math.abs(o - a) > i) return !1; } return !0; } easeInOutCubic(t) { return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; } } const ZS = ["x", "y", "z", "w"], $ = new KS(); class Z_ { constructor(t) { r(this, "y"); r(this, "s"); r(this, "alpha", 0); this.setAlpha(t), this.y = null, this.s = null; } setAlpha(t) { if (t <= 0 || t > 1) throw new Error(); this.alpha = t; } filter(t, e) { e && this.setAlpha(e); let i; return this.y ? i = this.alpha * t + (1 - this.alpha) * this.s : i = t, this.y = t, this.s = i, i; } lastValue() { return this.y; } reset(t) { this.y = t, this.s = t; } } class Tf { /** 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(t, e = 1, i = 0, n = 1) { /** * An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available. */ r(this, "freq"); /** * Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter. */ r(this, "minCutOff"); /** * Parameter to reduce latency (> 0). Higher values make the filter react faster to changes. */ r(this, "beta"); /** * Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing. */ r(this, "dCutOff"); /** * The low-pass filter for the signal. */ r(this, "x"); /** * The low-pass filter for the derivates. */ r(this, "dx"); /** * The last time the filter was called. */ r(this, "lasttime"); if (t <= 0 || e <= 0 || n <= 0) throw new Error(); this.freq = t, this.minCutOff = e, this.beta = i, this.dCutOff = n, this.x = new Z_(this.alpha(this.minCutOff)), this.dx = new Z_(this.alpha(this.dCutOff)), this.lasttime = null; } alpha(t) { const e = 1 / this.freq; return 1 / (1 + 1 / (2 * Math.PI * t) / e); } /** Filter your value: call with your value and the current timestamp (e.g. from this.context.time.time) */ filter(t, e = null) { this.lasttime && e && (this.freq = 1 / (e - this.lasttime)), this.lasttime = e; const i = this.x.lastValue(), n = i ? (t - i) * this.freq : 0, o = this.dx.filter(n, this.alpha(this.dCutOff)), a = this.minCutOff + this.beta * Math.abs(o); return this.x.filter(t, this.alpha(a)); } reset(t) { t != null && this.x.reset(t), this.x.alpha = this.alpha(this.minCutOff), this.dx.alpha = this.alpha(this.dCutOff), this.lasttime = null; } } class M0 { /** 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(t, e = 1, i = 0, n = 1) { r(this, "x"); r(this, "y"); r(this, "z"); this.x = new Tf(t, e, i, n), this.y = new Tf(t, e, i, n), this.z = new Tf(t, e, i, n); } filter(t, e, i = null) { e.x = this.x.filter(t.x, i), e.y = this.y.filter(t.y, i), e.z = this.z.filter(t.z, i); } reset(t) { this.x.reset(t == null ? void 0 : t.x), this.y.reset(t == null ? void 0 : t.y), this.z.reset(t == null ? void 0 : t.z); } } const dd = "needle:cameraController"; function JS(s) { return s[dd]; } function J_(s, t, e) { e ? s[dd] = t : s[dd] === t && (s[dd] = null); } const sm = "needle:autofit"; function eC(s) { return s[sm] === void 0 ? !0 : s[sm] !== !1; } function om(s, t) { s[sm] = t; } function dD(s, t, e) { const i = s.length(), n = t.length(), o = $.lerp(i, n, e); return s.lerp(t, e).normalize().multiplyScalar(o); } const Af = new W(), R0 = new W().setFromAxisAngle(new v(0, 1, 0), Math.PI); function uD(s, t) { s.lookAt(t), s.quaternion.multiply(R0); } function Tu(s, t, e = !0, i = !1) { if (s === t) return; Af.copy(s.quaternion); const n = ie(t), o = ie(s); if (i) { if (vn(s, Ce(t)), e) { const a = o.y, l = o.sub(cC(s)); l.y = a, s.lookAt(l), s.quaternion.multiply(R0); } Number.isNaN(s.quaternion.x) && s.quaternion.copy(Af); return; } e && (n.y = o.y), s.lookAt(n), Number.isNaN(s.quaternion.x) && s.quaternion.copy(Af); } function fD(s, t, e, i = 1) { if (e) { const n = G(0, 0, 0), o = t.x / window.innerWidth * 2 - 1, a = -(t.y / window.innerHeight) * 2 + 1; n.set( o, a, 0 ), n.unproject(e); const l = e.worldPosition, c = s.worldPosition.distanceTo(l), h = n.sub(l); h.multiplyScalar(i * 3.6 * c); const d = e.worldPosition.add(h); return s.lookAt(d), d; } return null; } const tC = new tn(() => new v(), 100); function G(s, t, e) { const i = tC.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 = t !== void 0 ? t : i.x, i.z = e !== void 0 ? e : i.x) : typeof s == "object" && (i.x = s.x, i.y = s.y, i.z = s.z), i; } const iC = new tn(() => new ce(), 30); function nC(s) { const t = iC.get(); return s ? t.copy(s) : t.set(0, 0, 0), t; } const sC = new tn(() => new W(), 100); function An(s) { const t = sC.get(); return t.identity(), s instanceof W ? t.copy(s) : s instanceof DOMPointReadOnly && t.set(s.x, s.y, s.z, s.w), t; } const mg = new tn(() => new v(), 100), ey = Symbol("lastMatrixWorldUpdateKey"); function ie(s, t = null, e = !0) { const i = t ?? mg.get(); return s ? s.parent ? (e && s.updateWorldMatrix(!0, !1), s.matrixWorldNeedsUpdate && s[ey] !== Date.now() && (s[ey] = Date.now(), s.updateMatrixWorld()), i.setFromMatrixPosition(s.matrixWorld), i) : i.copy(s.position) : i.set(0, 0, 0); } function yt(s, t) { if (!s) return s; const e = mg.get(); return t !== e && e.copy(t), ((s == null ? void 0 : s.parent) ?? s).worldToLocal(e), s.position.set(e.x, e.y, e.z), s; } function Fa(s, t, e, i) { const n = mg.get(); return n.set(t, e, i), yt(s, n), s; } const Fd = new tn(() => new W(), 100), hr = new W(), Ef = new W(); function Ce(s, t = null) { if (!s) return Fd.get().identity(); const e = t ?? Fd.get(); return s.parent ? (s.getWorldQuaternion(e), e) : e.copy(s.quaternion); } function vn(s, t) { if (!s) return; t !== hr && hr.copy(t); const e = hr, i = s == null ? void 0 : s.parent; i == null || i.getWorldQuaternion(Ef), Ef.invert(); const n = Ef.multiply(e); s.quaternion.set(n.x, n.y, n.z, n.w); } function k0(s, t, e, i, n) { hr.set(t, e, i, n), vn(s, hr); } const oC = new tn(() => new v(), 100), rC = new v(); function Ke(s, t = null) { return t || (t = oC.get()), s ? s.parent ? (s.getWorldScale(t), t) : t.copy(s.scale) : t.set(0, 0, 0); } function jc(s, t) { if (!s) return; if (!s.parent) { s.scale.copy(t); return; } const e = rC; s.parent.getWorldScale(e), s.scale.copy(t), s.scale.divide(e); } const aC = new v(), ty = new W(); function pD(s) { return Ce(s, ty), aC.set(0, 0, 1).applyQuaternion(ty); } const lC = new tn(() => new v(), 100), iy = new W(); function cC(s, t) { return t || (t = lC.get().set(0, 0, 1)), Ce(s, iy), t.applyQuaternion(iy); } const ny = new jt(), sy = new jt(), hC = new v(); function T0(s) { const t = Fd.get(); return s.getWorldQuaternion(t), sy.setFromQuaternion(t), sy; } function A0(s, t) { const e = Fd.get(); vn(s, e.setFromEuler(t)); } function Au(s) { const t = T0(s), e = hC; return e.set(t.x, t.y, t.z), e.x = $.toDegrees(e.x), e.y = $.toDegrees(e.y), e.z = $.toDegrees(e.z), e; } function E0(s, t) { Eu(s, t.x, t.y, t.z, !0); } function Eu(s, t, e, i, n = !0) { n && (t = $.toRadians(t), e = $.toRadians(e), i = $.toRadians(i)), ny.set(t, e, i), hr.setFromEuler(ny), vn(s, hr); } function rm(s, t = !0) { s && (t ? function e(i) { console.groupCollapsed((i.name ? i.name : "(no name : " + i.type + ")") + " %o", i), i.children.forEach(e), console.groupEnd(); }(s) : s.traverse(function(e) { for (var i = "|___", n = e; n.parent !== null; ) i = " " + i, n = n.parent; console.log(i + e.name + " <" + e.type + ">"); })); } function mD(s) { let t = (s == null ? void 0 : s.name) || ""; if (!s) return t; let e = s.parent; for (; e; ) t = e.name + "/" + t, e = e.parent; return t; } function dC(s) { if (s) { const t = s; return t.blendMode !== void 0 && t.clampWhenFinished !== void 0 && t.enabled !== void 0 && t.fadeIn !== void 0 && t.getClip !== void 0; } return !1; } class pn { /** * Create a blit material for copying textures */ static createBlitMaterial(t) { return new bn({ uniforms: { map: new ho(null) }, vertexShader: this.vertex, fragmentShader: t }); } /** * 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(t, e) { this.blitMaterial || (this.blitMaterial = new bn({ uniforms: { map: new ho(null) }, vertexShader: this.vertex, fragmentShader: this.fragment })); const i = e || this.blitMaterial; i.uniforms.map.value = t, i.needsUpdate = !0, i.uniformsNeedUpdate = !0; const n = i.vertexShader; i.vertexShader = this.vertex, this.mesh || (this.mesh = new q(this.planeGeometry, this.blitMaterial)); const o = this.mesh; o.material = i, o.frustumCulled = !1, this.scene.children.length = 0, this.scene.add(o), this.renderer || (this.renderer = new kr({ antialias: !1 })), this.renderer.setSize(t.image.width, t.image.height), this.renderer.clear(), this.renderer.render(this.scene, this.perspectiveCam); const a = new Fe(this.renderer.domElement); return a.name = "Copy", a.needsUpdate = !0, i.vertexShader = n, a; } // static blit(src: Texture, target: Texture, blitMaterial?: ShaderMaterial) { // let material = blitMaterial ?? this.blipMaterial; // material.uniforms.map.value = src; // this.mesh.material = material; // this.mesh.frustumCulled = false; // this.mesh.matrix.identity(); // this.scene.children.length = 0; // this.scene.add(this.mesh); // this.renderer.setSize(src.image.width, src.image.height); // this.renderer.clear(); // this.renderer.render(this.scene, this.perspectiveCam); // return new Texture(this.renderer.domElement); // } /** * 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(t, e = !1) { if (!t) return null; (e === !0 || t.isCompressedTexture === !0) && (t = uC(t)); const i = t.image; if (fC(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; } } r(pn, "planeGeometry", new qn(2, 2, 1, 1)), r(pn, "renderer"), r(pn, "perspectiveCam", new be()), r(pn, "scene", new Mi()), r(pn, "vertex", ` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy * 1.0,0.,.999999); }`), r(pn, "fragment", ` uniform sampler2D map; varying vec2 vUv; void main(){ vec2 uv = vUv; uv.y = 1.0 - uv.y; gl_FragColor = texture2D( map, uv); // gl_FragColor = vec4(uv.xy, 0, 1); }`), r(pn, "blitMaterial"), r(pn, "mesh"); function uC(s) { return pn.copyTexture(s); } function gD(s, t = !1) { return pn.textureToCanvas(s, t); } function fC(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 pC(s) { const t = s.type; return t === "Mesh" || t === "SkinnedMesh"; } function I0(s, t) { t ? s["needle:rendercustomshadow"] = !0 : s["needle:rendercustomshadow"] = !1; } function mC(s) { if (s) { if (s["needle:rendercustomshadow"] === !0) return !0; if (s["needle:rendercustomshadow"] == null) return !0; } return !1; } function ki(s, t = void 0, e = void 0, i = void 0) { const n = i || new Pi(); n.makeEmpty(); const o = []; function a(c) { let h = !0; if (c.visible && eC(c) !== !1 && !(c.type === "TransformControlsGizmo" || c.type === "TransformControlsPlane")) { if (c instanceof Zb && (h = !1), c instanceof ig && (h = !1), c instanceof Ba && (h = !1), c.isGizmo === !0 && (h = !1), c.material instanceof Kb && (h = !1), pC(c) || (h = !1), e && c.layers.test(e) === !1 && (h = !1), h) { if (t && Array.isArray(t) && (t != null && t.includes(c))) return; if (typeof t == "function" && t(c) === !0) return; } if (c.isUI !== !0) { if (h) { const d = c.children; c.children = o; const u = c.position, p = c.scale; if (Number.isNaN(u.x) || Number.isNaN(u.y) || Number.isNaN(u.z)) { console.warn(`Object "${c.name}" has NaN values in position or scale.... will ignore it`, u, p); return; } n.expandByObject(c, !0), c.children = d; } for (const d of c.children) a(d); } } } let l = !1; Array.isArray(s) || (s = [s]); for (const c of s) c && (l = !0, c.updateMatrixWorld(), a(c)); return l || console.warn("No objects to fit camera to..."), n; } function gC(s, t, e) { const i = ki([s], e == null ? void 0 : e.ignore), n = new v(); i.getSize(n); const o = new v(); i.getCenter(o); const a = new v(); t.getSize(a); const l = new v(); t.getCenter(l); const c = new v(); c.set(a.x / n.x, a.y / n.y, a.z / n.z); const h = Math.min(c.x, c.y, c.z), d = (e == null ? void 0 : e.scale) !== !1; if (d && jc(s, Ke(s).multiplyScalar(h)), (e == null ? void 0 : e.position) !== !1) { const u = new v(); i.getCenter(u), u.y = i.min.y; const p = new v(); t.getCenter(p), p.y = t.min.y; const m = p.clone().sub(u); d && m.multiplyScalar(h), yt(s, ie(s).add(m)); } return { boundsBefore: i, scale: c }; } function _C(s, t) { const e = ki([s]), i = new v(); e.getCenter(i), i.y = e.min.y; const n = t.clone().sub(i), o = ie(s); return yt(s, o.add(n)), { offset: n, bounds: e }; } function D0(s, t, e, i) { if (Array.isArray(t)) { let a = !0; for (let l = 0; l < t.length; l++) D0(s, t[l], l, t) || (a = !1); return a; } if (t.type === "MeshStandardMaterial" || t.type === "MeshBasicMaterial") return !1; if (t["material:fbx"] != null) return !0; const n = new It(); n["material:fbx"] = t; const o = t; 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), e === void 0 ? s.material = n : i[e] = n, !0; } let kh = !1; $S((...s) => { var t; z() && ((t = pe.Current) != null && t.isInXR) && (xa(!0), L0("error", ...s)); }); function xa(s) { if (s) { if (kh) return; kh = !0, bC(); } else { if (!kh) return; kh = !1, vC(); } } const lc = { log: void 0, warn: void 0, error: void 0 }; class yC { constructor() { r(this, "familyName", "needle-xr"); r(this, "root", null); r(this, "context", null); r(this, "defaultFontSize", 0.06); r(this, "targetObject", new L()); /** this is a point in forward view of the user */ r(this, "userForwardViewPoint", new v()); r(this, "oneEuroFilter", new M0(90, 0.8)); r(this, "_lastElementRemoveTime", 0); r(this, "onBeforeRender", () => { var e, i; const t = (e = this.context) == null ? void 0 : e.mainCamera; if (this.context && t instanceof be) { const n = this.getRoot(); Number.isNaN(n.position.x) && n.position.set(0, 0, 0), Number.isNaN(n.quaternion.x) && n.quaternion.set(0, 0, 0, 1), this.context.scene.add(this.targetObject); const o = ((i = this.context.xr) == null ? void 0 : i.rigScale) ?? 1, a = 3.5 * o, l = t.worldForward; l.y = 0, l.normalize().multiplyScalar(a), this.userForwardViewPoint.copy(t.worldPosition).sub(l), this.targetObject.position.distanceTo(this.userForwardViewPoint) > 2 * o && (this.targetObject.position.copy(this.userForwardViewPoint), Tu(this.targetObject, t, !0, !0), this.targetObject.rotateY(Math.PI)), this.oneEuroFilter.filter(this.targetObject.position, n.position, this.context.time.time); const h = this.context.time.deltaTime; if (n.quaternion.slerp(this.targetObject.quaternion, h * 5), n.scale.setScalar(o), this.targetObject.removeFromParent(), this.context.scene.add(n), this.context.time.time - this._lastElementRemoveTime > 0.1) { this._lastElementRemoveTime = this.context.time.time; const d = Date.now(); for (let u = 0; u < this._activeTexts.length; u++) { const p = this._activeTexts[u]; if (p instanceof Te.Text && d - p._activatedTime > 2e4) { p.removeFromParent(), this._textBuffer.push(p), this._activeTexts.splice(u, 1); break; } } } } }); r(this, "textOptions", { fontSize: this.defaultFontSize, fontFamily: this.familyName, padding: 0.03, margin: 5e-3, color: 0, backgroundColor: 16777215, backgroundOpacity: 0.4, borderRadius: 0.03, offset: 0.025 }); r(this, "_textBuffer", []); r(this, "_activeTexts", []); this.ensureFont(); } onEnable() { this.context = pe.Current || pe