UNPKG

@tresjs/core

Version:

Declarative ThreeJS using Vue Components

1,503 lines (1,502 loc) 163 kB
/** * name: @tresjs/core * version: v5.1.0 * (c) 2025 * description: Declarative ThreeJS using Vue Components * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/) */ import { reactive as Io, toValue as I, watch as At, onUnmounted as ie, defineComponent as ot, renderSlot as Do, unref as ke, ref as Ae, computed as J, watchEffect as $, readonly as zt, shallowRef as it, isRef as me, useSlots as ko, getCurrentInstance as $t, onMounted as Kt, createElementBlock as xo, openBlock as Ro, normalizeStyle as Lo, normalizeClass as Fo, createRenderer as Mo, h as Wt, provide as qe, Fragment as No } from "vue"; import * as vr from "three"; import { Layers as Vo, Scene as yr, MathUtils as Bo, Clock as Uo, WebGLRenderer as Cr, Mesh as He, Material as Ho, Vector3 as D, Vector2 as Y, Ray as st, SphereGeometry as jo, Object3D as je, Matrix4 as Te, BufferAttribute as br, Triangle as wr, Line3 as zo, Plane as ze, Raycaster as $o, Quaternion as at, Sphere as Ko, MeshBasicMaterial as Ar, DoubleSide as Wo, Color as xe, PCFSoftShadowMap as Go, ACESFilmicToneMapping as Yo, PerspectiveCamera as qo, ArrowHelper as Xo, Line as Qo, BufferGeometry as Gt, Float32BufferAttribute as Yt, LineBasicMaterial as Zo, BackSide as Jo, HemisphereLightHelper as ei, SpotLightHelper as ti, PointLightHelper as ni, DirectionalLightHelper as ri } from "three"; import { useAsyncState as oi, whenever as qt, tryOnScopeDispose as ii, createEventHook as Ee, useRafFn as Tr, useDevicePixelRatio as si, useTimeout as ai, unrefElement as ui, useWindowSize as li, useElementSize as ci, refDebounced as Xt, createInjectionState as fi, useFps as di, useMemory as pi, promiseTimeout as hi } from "@vueuse/core"; const _i = "@tresjs/core", mi = "module", gi = "5.1.0", Ei = "pnpm@10.17.0", vi = "Declarative ThreeJS using Vue Components", yi = "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)", Ci = "MIT", bi = { type: "git", url: "git+https://github.com/Tresjs/tres.git", directory: "packages/core" }, wi = ["vue", "3d", "threejs", "three", "threejs-vue"], Ai = !1, Ti = { ".": { types: "./dist/index.d.ts", import: "./dist/tres.js", default: "./dist/tres.js" }, "./components": { types: "./dist/src/components/index.d.ts" }, "./composables": { types: "./dist/src/composables/index.d.ts" }, "./types": { types: "./dist/src/types/index.d.ts" }, "./utils": { types: "./dist/src/utils/index.d.ts" }, "./*": "./*" }, Oi = "./dist/tres.js", Si = "./dist/index.d.ts", Pi = ["*.d.ts", "dist"], Ii = { access: "public" }, Di = { build: "vite build", test: "vitest", "test:ci": "vitest run", "test:ui": "vitest --ui --coverage.enabled=true", coverage: "vitest run --coverage", lint: "eslint .", "lint:fix": "eslint . --fix", typecheck: "vue-tsc --noEmit" }, ki = { three: ">=0.133", vue: ">=3.4" }, xi = { "@pmndrs/pointer-events": "^6.6.17", "@vue/devtools-api": "^7.7.2", "@vueuse/core": "catalog:", radashi: "^12.6.2" }, Ri = { "@tresjs/eslint-config": "workspace:*", "@types/three": "catalog:", "@typescript-eslint/eslint-plugin": "catalog:", "@typescript-eslint/parser": "catalog:", "@vitejs/plugin-vue": "catalog:", "@vitest/coverage-v8": "3.2.4", "@vitest/ui": "catalog:", "@vue/test-utils": "catalog:", eslint: "catalog:", "eslint-plugin-vue": "catalog:", jsdom: "catalog:", kolorist: "catalog:", pathe: "catalog:", "rollup-plugin-analyzer": "catalog:", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-visualizer": "catalog:", three: "catalog:", vite: "catalog:", "vite-plugin-banner": "catalog:", "vite-plugin-dts": "catalog:", "vite-plugin-inspect": "^11.3.3", vitest: "catalog:", vue: "catalog:", "vue-demi": "^0.14.10", "vue-tsc": "catalog:" }, Li = { implicitDependencies: ["!@tresjs/core-*"] }, Fi = { name: _i, type: mi, version: gi, packageManager: Ei, description: vi, author: yi, license: Ci, repository: bi, keywords: wi, sideEffects: Ai, exports: Ti, module: Oi, types: Si, files: Pi, publishConfig: Ii, scripts: Di, peerDependencies: ki, dependencies: xi, devDependencies: Ri, nx: Li }; /*! #__NO_SIDE_EFFECTS__ */ // @__NO_SIDE_EFFECTS__ function Mi(e) { const t = /* @__PURE__ */ Object.create(null); for (const n of e.split(",")) t[n] = 1; return (n) => n in t; } const Ni = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot", Vi = /* @__PURE__ */ Mi(Ni); function Qt(e) { var t; const n = ((t = e?.replace(/([A-Z])+/g, Bi)) == null ? void 0 : t.split(/(?=[A-Z])|[\.\-\s_]/).map((r) => r.toLowerCase())) ?? []; return n.length === 0 ? "" : n.length === 1 ? n[0] : n.reduce((r, o) => `${r}${o.charAt(0).toUpperCase()}${o.slice(1)}`); } function Bi(e) { if (!e || e.length === 0) return ""; const t = e.toLowerCase(); return t.substring(0, 1).toUpperCase() + t.substring(1, t.length); } function Or(e, t) { if (Object.is(e, t)) return !0; if (e instanceof Date && t instanceof Date) return e.getTime() === t.getTime(); if (e instanceof RegExp && t instanceof RegExp) return e.toString() === t.toString(); if (typeof e != "object" || e === null || typeof t != "object" || t === null) return !1; const n = Reflect.ownKeys(e), r = Reflect.ownKeys(t); if (n.length !== r.length) return !1; for (let o = 0; o < n.length; o++) if (!Reflect.has(t, n[o]) || !Or(e[n[o]], t[n[o]])) return !1; return !0; } function Q(e) { return typeof e == "function"; } function Sr(e) { return typeof e == "number" && !Number.isNaN(e); } function Tt(e) { return Ui(e, "[object Object]"); } function Ot(e) { return typeof e == "string"; } function Ui(e, t) { return Object.prototype.toString.call(e) === t; } function ut(e) { return typeof e > "u"; } const B = (e) => (t) => Tt(t) && e in t && !!t[e], lt = B("isObject3D"), $e = B("isMesh"), Pr = B("isCamera"), Hi = B("isOrthographicCamera"), Ir = B("isPerspectiveCamera"), Dr = B("isColor"), ji = (e) => Ot(e) || Sr(e) || Dr(e), Zt = (e) => e instanceof Vo, kr = B("isBufferGeometry"), xr = B("isMaterial"), Rr = B("isLight"), Lr = B("isFog"), Fr = B("isScene"), cl = B("isGroup"), ct = (e) => e !== null && typeof e == "object" && "set" in e && typeof e.set == "function", zi = (e) => ct(e) && "copy" in e && typeof e.copy == "function", $i = (e) => !!e?.constructor, re = (e) => Pr(e) || Hi(e) || Ir(e), Ki = (e) => ( // NOTE: TresObject is currently defined as // TresObject3D | THREE.BufferGeometry | THREE.Material | THREE.Fog lt(e) || kr(e) || xr(e) || Lr(e) ), Wi = B("isPrimitive"), Gi = (e) => Ki(e) && "__tres" in e, Yi = (e, t) => { let n = 0; for (let r = 0; r < e.length; r++) t(e[r], r) && (e[n] = e[r], n++); return e.length = n, e; }, fl = !0, Fe = "[TresJS ▲ ■ ●] "; function Jt(...e) { typeof e[0] == "string" ? e[0] = Fe + e[0] : e.unshift(Fe), console.error(...e); } function Me(...e) { typeof e[0] == "string" ? e[0] = Fe + e[0] : e.unshift(Fe), console.warn(...e); } function dl(e, t) { } function en(e) { ((n) => "map" in n && !!n.map)(e) && e.map.dispose(), e.dispose(); } function Ne(e) { if (e.parent && e.removeFromParent?.(), delete e.__tres, [...e.children].forEach((n) => Ne(n)), !(e instanceof yr)) { const n = e; e && e.dispose?.(), n.geometry && n.geometry.dispose(), Array.isArray(n.material) ? n.material.forEach((r) => en(r)) : n.material && en(n.material); } } function Ve(e, t) { let n = e; if (t.includes("-")) { const r = t.split("-"); let o = r.shift(); for (; n && r.length; ) o in n ? (n = n[o], o = r.shift()) : o = tn(o, r.shift()); return { target: n, key: tn(o, ...r) }; } else return { target: n, key: t }; } function tn(...e) { return e.map((t, n) => n === 0 ? t : t.charAt(0).toUpperCase() + t.slice(1)).join(""); } function qi(e, t, n) { const r = /-\d+$/; if (Ot(n)) { if (r.test(n)) { const s = n.replace(r, ""), { target: a, key: u } = Ve(e, s); if (!Array.isArray(a[u])) { const l = a[u], c = []; c.__tresDetach = () => { c.every((f) => ut(f)) && (a[u] = l); }, a[u] = c; } } const { target: o, key: i } = Ve(e, n); t.__tres.previousAttach = o[i], o[i] = se(t); } else t.__tres.previousAttach = n(e, t); } function Xi(e, t, n) { if (Ot(n)) { const { target: r, key: o } = Ve(e, n), i = t.__tres.previousAttach; i === void 0 ? delete r[o] : r[o] = i, "__tresDetach" in r && r.__tresDetach(); } else t.__tres?.previousAttach?.(e, t); delete t.__tres?.previousAttach; } function X(e, t, n) { const r = e; return r.__tres = { type: "unknown", root: n, memoizedProps: {}, objects: [], parent: null, previousAttach: null, ...t }, r.__tres.attach || (xr(r) ? r.__tres.attach = "material" : kr(r) ? r.__tres.attach = "geometry" : Lr(r) && (r.__tres.attach = "fog")), r; } function ft(e) { const t = e?.__tres?.root; t?.renderer && t.renderer.canBeInvalidated.value && t.renderer.invalidate(); } function Qi(e, t, n, r, o) { const i = [...t.__tres.objects], s = se(t); if (e = se(e), s === e) return !0; const a = X(e, t.__tres ?? {}, o), u = t.parent ?? t.__tres.parent ?? null, l = { ...t.__tres.memoizedProps }; delete l.object; for (const c of i) Mr(c, o), Nr(c, o); s.__tres.objects = [], r.remove(t); for (const [c, f] of Object.entries(l)) r.patchProp(a, c, a[c], f); n(e), r.insert(t, u); for (const c of i) r.insert(c, t); return !0; } function se(e) { if (Wi(e)) { const t = e; return t.object.__tres = t.__tres, t.object; } else return e; } function Mr(e, t) { const n = e.__tres?.parent || t.scene.value; e.__tres && (e.__tres.parent = null), n && n.__tres && "objects" in n.__tres && Yi(n.__tres.objects, (r) => r !== e), e.__tres?.attach ? Xi(n, e, e.__tres.attach) : (e.parent?.remove?.(se(e)), e.parent = null); } function Nr(e, t) { e.traverse?.((n) => { re(n) && t.camera.deregisterCamera(n); }), re(e) && t.camera.deregisterCamera(e), ft(e); } function Zi(e, t, n) { const r = new e(n?.manager), o = Io({ loaded: 0, total: 0, percentage: 0 }); n?.extensions && n.extensions(r); const i = I(t), s = oi( (u) => new Promise((l, c) => { const f = u || i || ""; r.load(f, (h) => { l(h); }, (h) => { o.loaded = h.loaded, o.total = h.total, o.percentage = o.loaded / o.total * 100; }, (h) => { c(h); }); }), n?.initialValue ?? null, { ...n?.asyncOptions, immediate: n?.asyncOptions?.immediate ?? !0 } ), a = At(() => I(t), (u) => { if (u) { const l = s.state.value; l && typeof l == "object" && "scene" in l && l.scene && Ne(l.scene), s.execute(0, u); } }); return ie(() => { a(); const u = s.state.value; u && typeof u == "object" && "scene" in u && u.scene && Ne(u.scene); }), { ...s, load: (u) => { s.execute(0, u); }, progress: o }; } const pl = /* @__PURE__ */ ot({ __name: "component", props: { loader: {}, path: {}, manager: {} }, emits: ["loaded", "error"], setup(e, { emit: t }) { const n = e, r = t, { state: o, isLoading: i, error: s } = Zi(n.loader, n.path, { manager: n.manager }); return qt(s, (a) => { a && r("error", a); }), qt(o, (a) => { a && r("loaded", a); }), (a, u) => Do(a.$slots, "default", { state: ke(o), isLoading: ke(i), error: ke(s) }); } }), Ji = ({ sizes: e }) => { const t = Ae([]), n = J(() => t.value[0]), r = (s) => { const a = Pr(s) ? s : t.value.find((l) => l.uuid === s); if (!a) return; const u = t.value.filter(({ uuid: l }) => l !== a.uuid); t.value = [a, ...u]; }, o = (s, a = !1) => { t.value.some(({ uuid: u }) => u === s.uuid) || (t.value.push(s), a && r(s.uuid)); }, i = (s) => { t.value = t.value.filter(({ uuid: a }) => a !== s.uuid); }; return $(() => { e.aspectRatio.value && t.value.forEach((s) => { Ir(s) && (s.aspect = e.aspectRatio.value, s.updateProjectionMatrix()); }); }), { activeCamera: n, cameras: t, registerCamera: o, deregisterCamera: i, setActiveCamera: r }; }; function es(e) { const t = { nodes: {}, materials: {}, meshes: {} }; return e && e.traverse((n) => { n.name && (t.nodes[n.name] = n), $e(n) && (t.meshes[n.name] || (t.meshes[n.name] = n), (Array.isArray(n.material) ? n.material : [n.material]).forEach((r) => { r.name && !t.materials[r.name] && (t.materials[r.name] = r); })); }), t; } const hl = (e) => J(() => { const t = I(e); if (t) return es(t); }); function nn() { const e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Set(); let n = 0, r = !1; const o = () => { const l = Array.from(e.entries()).sort((c, f) => { const h = c[1].priority - f[1].priority; return h === 0 ? c[1].addI - f[1].addI : h; }); t.clear(), l.forEach((c) => t.add(c[0])); }, i = (l) => { e.delete(l), t.delete(l); }; return { on: (l, c = 0) => { e.set(l, { priority: c, addI: n++ }); const f = () => i(l); return ii(f), r = !0, { off: f }; }, off: i, trigger: (...l) => (r && (o(), r = !1), Promise.all( Array.from(t).map((c) => c(...l)) )), dispose: () => { e.clear(), t.clear(); }, get count() { return e.size; } }; } const dt = Ae({}), pt = (e) => Object.assign(dt.value, e), ts = (e, t, n) => { if (!Q(e.setPixelRatio)) return; let r = 0; if (n && Array.isArray(n) && n.length >= 2) { const [o, i] = n; r = Bo.clamp(t, o, i); } else Sr(n) ? r = n : r = t; r !== e.getPixelRatio?.() && e.setPixelRatio(r); }, ns = (e) => { const t = new Uo(), n = { before: Ee(), after: Ee() }, { pause: r, resume: o, isActive: i } = Tr(() => { const u = () => ({ delta: t.getDelta(), elapsed: t.elapsedTime }); n.before.trigger(u()), e(), n.after.trigger(u()); }, { immediate: !1 }); return { start: () => { t.start(), o(); }, stop: () => { t.stop(), r(); }, isActive: i, onBeforeLoop: n.before.on, onLoop: n.after.on }; }; function rs({ scene: e, canvas: t, options: n, contextParts: { sizes: r, camera: o } }) { const s = Q(n.renderer) ? n.renderer({ sizes: r, scene: e, camera: o, canvas: t }) : new Cr({ ...n, canvas: ui(t) }), a = Ae(I(n.renderMode) === "manual" ? 0 : 1), u = 60, l = J(() => I(n.renderMode) === "on-demand" && a.value === 0), c = () => e.value.traverse((E) => { E instanceof He && E.material instanceof Ho && (E.material.needsUpdate = !0); }), f = (E = 1) => { l.value && (a.value = Math.min(u, a.value + E)); }, h = () => { if (I(n.renderMode) !== "manual") throw new Error("advance can only be called in manual render mode."); a.value = 1; }, d = () => { I(n.renderMode) === "on-demand" && f(); }, _ = J(() => I(n.renderMode) === "always"), v = (E) => Tt(E) && "isRenderer" in E && !!E.isRenderer, p = Ee(); let g = !1; v(s) && (s.init(), p.trigger(s)); const C = Ee(), b = () => { a.value = _.value ? 1 : Math.max(0, a.value - 1), C.trigger(s); }; let P = (E) => { o.activeCamera.value && (s.render(e.value, o.activeCamera.value), E()); }; const M = (E) => { P = E; }, A = ns(() => { a.value && P(b); }); p.on(A.start), At([r.width, r.height], () => { s.setSize(r.width.value, r.height.value), !g && s.domElement.width && s.domElement.height && (p.trigger(s), g = !0), d(); }, { immediate: !0 }); const { pixelRatio: O } = si(); $(() => { ts(s, O.value, I(n.dpr)); }), I(n.renderMode) === "on-demand" && f(), I(n.renderMode) === "manual" && ai(100, { callback: h }); const T = J(() => { const E = I(n.clearColor), x = I(n.clearAlpha), R = typeof E == "string" && E.length === 9 && E.startsWith("#"); return R && x !== void 0 && Me(`clearColor with alpha (e.g. ${E}) and clearAlpha cannot both be set, using clearColor as source of truth`), R ? { alpha: Number.parseInt(E.slice(7, 9), 16) / 255, color: E.slice(0, 7) } : { alpha: x, color: E }; }); return $(() => { const E = T.value; E.color === void 0 || E.alpha === void 0 || s.setClearColor(E.color, E.alpha); }), $(() => { const E = n.toneMapping; E && (s.toneMapping = E); }), $(() => { const E = n.toneMappingExposure; E && (s.toneMappingExposure = E); }), $(() => { const E = n.outputColorSpace; E && (s.outputColorSpace = E); }), $(() => { const E = n.shadows; E !== void 0 && (s.shadowMap.enabled = E, c()); }), $(() => { const E = n.shadowMapType; E !== void 0 && (s.shadowMap.type = E, c()); }), ie(() => { s.dispose(), "forceContextLoss" in s && s.forceContextLoss(); }), { loop: A, instance: s, advance: h, onReady: p.on, onRender: C.on, invalidate: f, canBeInvalidated: l, mode: I(n.renderMode), replaceRenderFunction: M }; } function os(e, t, n = 10) { const r = I(e) ? li() : ci(J(() => I(t).parentElement)), o = zt(Xt(r.width, n)), i = zt(Xt(r.height, n)), s = J(() => o.value / i.value); return { height: i, width: o, aspectRatio: s }; } class is { nativeEvent; NONE = 0; CAPTURING_PHASE = 1; AT_TARGET = 2; BUBBLING_PHASE = 3; relatedTarget = null; get altKey() { return this.getFromNative("altKey", !1); } get button() { return this.getFromNative("button", 0); } get buttons() { return this.getFromNative("buttons", 0); } get clientX() { return this.getFromNative("clientX", 0); } get clientY() { return this.getFromNative("clientY", 0); } get ctrlKey() { return this.getFromNative("ctrlKey", !1); } get layerX() { return this.getFromNative("layerX", 0); } get layerY() { return this.getFromNative("layerY", 0); } get metaKey() { return this.getFromNative("metaKey", !1); } get movementX() { return this.getFromNative("movementX", 0); } get movementY() { return this.getFromNative("movementY", 0); } get offsetX() { return this.getFromNative("offsetX", 0); } get offsetY() { return this.getFromNative("offsetY", 0); } get pageX() { return this.getFromNative("pageX", 0); } get pageY() { return this.getFromNative("pageY", 0); } get screenX() { return this.getFromNative("screenX", 0); } get screenY() { return this.getFromNative("screenY", 0); } get shiftKey() { return this.getFromNative("shiftKey", !1); } get x() { return this.getFromNative("x", 0); } get y() { return this.getFromNative("y", 0); } get detail() { return this.getFromNative("detail", 0); } get view() { return this.getFromNative("view", null); } get which() { return this.getFromNative("which", 0); } get cancelBubble() { return this.getFromNative("cancelBubble", !1); } get composed() { return this.getFromNative("composed", !1); } get eventPhase() { return this.getFromNative("eventPhase", 0); } get isTrusted() { return this.getFromNative("isTrusted", !1); } get returnValue() { return this.getFromNative("returnValue", !1); } get timeStamp() { return this.getFromNative("timeStamp", 0); } get cancelable() { return this.getFromNative("cancelable", !1); } get defaultPrevented() { return this.getFromNative("defaultPrevented", !1); } constructor(t) { this.nativeEvent = t; } getFromNative(t, n) { return t in this.nativeEvent ? this.nativeEvent[t] : n; } } const Xe = new D(); class L extends is { type; bubbles; internalPointer; intersection; camera; currentObject; object; propagationState; //--- pointer events data get pointerId() { return this.internalPointer.id; } get pointerType() { return this.internalPointer.type; } get pointerState() { return this.internalPointer.state; } //--- intersection data get distance() { return this.intersection.distance; } get distanceToRay() { return this.intersection.distanceToRay; } get point() { return this.intersection.point; } get index() { return this.intersection.index; } get face() { return this.intersection.face; } get faceIndex() { return this.intersection.faceIndex; } get uv() { return this.intersection.uv; } get uv1() { return this.intersection.uv1; } get normal() { return this.intersection.normal; } get instanceId() { return this.intersection.instanceId; } get pointOnLine() { return this.intersection.pointOnLine; } get batchId() { return this.intersection.batchId; } get pointerPosition() { return this.intersection.pointerPosition; } get pointerQuaternion() { return this.intersection.pointerQuaternion; } get pointOnFace() { return this.intersection.pointOnFace; } get localPoint() { return this.intersection.localPoint; } get details() { return this.intersection.details; } /** same as object */ get target() { return this.object; } /** same as currentObject */ get currentTarget() { return this.currentObject; } /** same as currentObject */ get eventObject() { return this.currentObject; } /** same as object */ get srcElement() { return this.currentObject; } _pointer; get pointer() { return this._pointer == null && (Xe.copy(this.intersection.point).project(this.camera), this._pointer = new Y(Xe.x, Xe.y)), this._pointer; } _ray; get ray() { if (this._ray != null) return this._ray; switch (this.intersection.details.type) { case "screen-ray": case "ray": case "sphere": return this._ray = new st(this.intersection.pointerPosition, new D(0, 0, -1).applyQuaternion(this.intersection.pointerQuaternion)); case "lines": return this._ray = new st(this.intersection.details.line.start, this.intersection.details.line.end.clone().sub(this.intersection.details.line.start).normalize()); } } _intersections = []; get intersections() { return this._intersections == null && (this._intersections = [{ ...this.intersection, eventObject: this.currentObject }]), this._intersections; } _unprojectedPoint; get unprojectedPoint() { if (this._unprojectedPoint == null) { const t = this.pointer; this._unprojectedPoint = new D(t.x, t.y, 0).unproject(this.camera); } return this._unprojectedPoint; } get stopped() { return this.propagationState.stoppedImmediate || this.propagationState.stopped; } get stoppedImmediate() { return this.propagationState.stoppedImmediate; } get delta() { throw new Error("not supported"); } constructor(t, n, r, o, i, s, a = i.object, u = a, l = { stopped: !n, stoppedImmediate: !1 }) { super(r), this.type = t, this.bubbles = n, this.internalPointer = o, this.intersection = i, this.camera = s, this.currentObject = a, this.object = u, this.propagationState = l; } stopPropagation() { this.propagationState.stopped = !0; } stopImmediatePropagation() { this.propagationState.stoppedImmediate = !0; } /** * for internal use */ retarget(t) { return new L(this.type, this.bubbles, this.nativeEvent, this.internalPointer, this.intersection, this.camera, t, this.target, this.propagationState); } } class Be extends L { get deltaX() { return this.nativeEvent.deltaX; } get deltaY() { return this.nativeEvent.deltaY; } get deltaZ() { return this.nativeEvent.deltaZ; } constructor(t, n, r, o, i, s) { super("wheel", !0, t, n, r, o, i, s); } /** * for internal use */ retarget(t) { return new Be(this.nativeEvent, this.internalPointer, this.intersection, this.camera, t, this.target); } } function N(e) { Vr(e, e.currentObject); } function Vr(e, t) { if (t == null) return; const n = as(t, e.type); if (n != null && n.length > 0) { const r = e.retarget(t), o = n.length; for (let i = 0; i < o && !r.stoppedImmediate; i++) n[i](r); } e.stopped || Vr(e, t.parent); } const Br = { click: "onClick", contextmenu: "onContextMenu", dblclick: "onDoubleClick", pointercancel: "onPointerCancel", pointerdown: "onPointerDown", pointerenter: "onPointerEnter", pointerleave: "onPointerLeave", pointermove: "onPointerMove", pointerout: "onPointerOut", pointerover: "onPointerOver", pointerup: "onPointerUp", wheel: "onWheel" }, ss = Object.keys(Br); function as(e, t) { if (e._listeners != null && t in e._listeners) return e._listeners[t]; let n; if (e.isVoidObject && t === "click" && e.parent?.__r3f != null && (n = e.parent.__r3f.root.getState().onPointerMissed), e.__r3f != null && (n = e.__r3f.handlers[Br[t]]), n != null) return [n]; } const us = 1e10, ls = new jo(us), rn = /* @__PURE__ */ new Map(); function Ur(e) { let t = rn.get(e); return t == null && (t = new He(ls), t.isVoidObject = !0, t.parent = e, t.pointerEventsOrder = -1 / 0, rn.set(e, t)), t; } function cs(e, t, n) { const r = t.normal ?? t.face?.normal; return r == null ? !1 : (e.setFromNormalAndCoplanarPoint(r, t.localPoint), e.applyMatrix4(n), !0); } function fs(e, t, n) { if (t === "none" || t === "listener" && !e) return !1; if (n === "all") return !0; if (typeof n == "function") return ({ id: i, type: s, state: a }) => n(i, s, a); let r, o; return "deny" in n ? (o = !0, r = n.deny) : (o = !1, r = n.allow), Array.isArray(r) ? (i) => on(r.includes(i.type), o) : (i) => on(r === i.type, o); } function on(e, t) { return t ? !e : e; } function Hr(e, t, n, r = !1, o, i, s) { const a = r || ds(e, t), u = t.pointerEvents ?? o, l = u ?? t.defaultPointerEvents ?? "listener", c = t.pointerEventsType ?? i ?? "all", f = t.pointerEventsOrder ?? s ?? 0, h = fs(a, l, c), d = n.length; if (d === 1) (h === !0 || typeof h == "function" && h(n[0])) && Qe(n[0], t, l, c, f); else if (h === !0) for (let p = 0; p < d; p++) Qe(n[p], t, l, c, f); else if (typeof h == "function") for (let p = 0; p < d; p++) { const g = n[p]; h(g) && Qe(g, t, l, c, f); } if (t.children.length === 0 || t.intersectChildren === !1) return; const _ = t.interactableDescendants ?? t.children, v = _.length; for (let p = 0; p < v; p++) Hr(e, _[p], n, a, u, c, f); } function ds(e, t) { if (t.ancestorsHaveListeners || e === "pointer" && t.ancestorsHavePointerListeners || e === "wheel" && t.ancestorsHaveWheelListeners || t.__r3f != null && t.__r3f?.eventCount > 0 && (e === "wheel" && t.__r3f.handlers.onWheel != null || e === "pointer" && Object.keys(t.__r3f.handlers).some((o) => o != "onWheel"))) return !0; if (t._listeners == null) return !1; if (e === "wheel") { const o = t._listeners.wheel; return o != null && o.length > 0; } const n = Object.entries(t._listeners), r = n.length; for (let o = 0; o < r; o++) { const i = n[o]; if (i[0] !== "wheel" && ss.includes(i[0]) && i[1] != null && i[1].length > 0) return !0; } return !1; } function Qe({ intersector: e, options: t }, n, r, o, i) { t.filter?.(n, r, o, i) !== !1 && e.executeIntersection(n, i); } function ps(e, t, { customSort: n = hs } = {}, r) { let o, i, s; const a = e.length; for (let u = 0; u < a; u++) { const l = e[u], c = t?.[u]; (o == null || n(l, c, o, i) < 0) && (s = u, o = l, i = c); } return s; } function hs(e, t = 0, n, r = 0) { return t != r ? r - t : e.distance - n.distance; } const sn = 1e7; function _s(e, t, n, r, o, i = 0) { const s = t.direction.clone().multiplyScalar(sn), a = sn; return { distance: a + i, object: Ur(e), point: s, normal: t.origin.clone().sub(s).normalize(), details: n(s, a), pointerPosition: r, pointerQuaternion: o, pointOnFace: s, localPoint: s }; } function ms(e, t, n) { for (; n > 0; ) e.push(t), --n; } const Ze = Symbol("buttonsDownTime"), gs = Symbol("buttonsClickTime"); globalThis.pointerEventspointerMap ??= /* @__PURE__ */ new Map(); je.prototype.setPointerCapture = function(e) { St(e)?.setCapture(this); }; je.prototype.releasePointerCapture = function(e) { const t = St(e); t == null || !t.hasCaptured(this) || t.setCapture(void 0); }; je.prototype.hasPointerCapture = function(e) { return St(e)?.hasCaptured(this) ?? !1; }; function St(e) { return globalThis.pointerEventspointerMap?.get(e); } class Es { id; type; state; intersector; getCamera; onMoveCommited; parentSetPointerCapture; parentReleasePointerCapture; options; //state prevIntersection; intersection; prevEnabled = !0; enabled = !0; wheelIntersection; //derived state /** * ordered leaf -> root (bottom -> top) */ pointerEntered = []; pointerEnteredHelper = []; pointerCapture; buttonsDownTime = /* @__PURE__ */ new Map(); buttonsDown = /* @__PURE__ */ new Set(); //to handle interaction before first move (after exit) wasMoved = !1; onFirstMove = []; constructor(t, n, r, o, i, s, a, u, l = {}) { this.id = t, this.type = n, this.state = r, this.intersector = o, this.getCamera = i, this.onMoveCommited = s, this.parentSetPointerCapture = a, this.parentReleasePointerCapture = u, this.options = l, globalThis.pointerEventspointerMap?.set(t, this); } getPointerCapture() { return this.pointerCapture; } hasCaptured(t) { return this.pointerCapture?.object === t; } setCapture(t) { this.pointerCapture?.object !== t && (this.pointerCapture != null && (this.parentReleasePointerCapture?.(), this.pointerCapture = void 0), t != null && this.intersection != null && (this.pointerCapture = { object: t, intersection: this.intersection }, this.parentSetPointerCapture?.())); } getButtonsDown() { return this.buttonsDown; } /** * @returns undefined if no intersection was executed yet */ getIntersection() { return this.intersection; } getEnabled() { return this.enabled; } setEnabled(t, n, r = !0) { this.enabled !== t && (!t && this.pointerCapture != null && (this.parentReleasePointerCapture?.(), this.pointerCapture = void 0), this.enabled = t, r && this.commit(n, !1)); } computeIntersection(t, n, r) { return this.pointerCapture != null ? this.intersector.intersectPointerCapture(this.pointerCapture, r) : (this.intersector.startIntersection(r), Hr(t, n, [this]), this.intersector.finalizeIntersection(n)); } setIntersection(t) { this.intersection = t; } commit(t, n) { const r = this.getCamera(), o = this.prevEnabled ? this.prevIntersection : void 0, i = this.enabled ? this.intersection : void 0; o != null && o.object != i?.object && N(new L("pointerout", !0, t, this, o, r)); const s = this.pointerEntered; this.pointerEntered = [], this.pointerEnteredHelper.length = 0, jr(i?.object, this.pointerEntered, s, this.pointerEnteredHelper); const a = s.length; for (let u = 0; u < a; u++) { const l = s[u]; N(new L("pointerleave", !1, t, this, o, r, l)); } i != null && o?.object != i.object && N(new L("pointerover", !0, t, this, i, r)); for (let u = this.pointerEnteredHelper.length - 1; u >= 0; u--) { const l = this.pointerEnteredHelper[u]; N(new L("pointerenter", !1, t, this, i, r, l)); } if (n && i != null && N(new L("pointermove", !0, t, this, i, r)), this.prevIntersection = this.intersection, this.prevEnabled = this.enabled, !this.wasMoved && this.intersector.isReady()) { this.wasMoved = !0; const u = this.onFirstMove.length; for (let l = 0; l < u; l++) this.onFirstMove[l](r); this.onFirstMove.length = 0; } this.onMoveCommited?.(this); } /** * computes and commits a move */ move(t, n) { this.intersection = this.computeIntersection("pointer", t, n), this.commit(n, !0); } /** * emits a move without (re-)computing the intersection * just emitting a move event to the current intersection */ emitMove(t) { this.intersection != null && N(new L("pointermove", !0, t, this, this.intersection, this.getCamera())); } down(t) { if (this.buttonsDown.add(t.button), !this.enabled) return; if (!this.wasMoved) { this.onFirstMove.push(this.down.bind(this, t)); return; } if (this.intersection == null) return; N(new L("pointerdown", !0, t, this, this.intersection, this.getCamera())); const { object: n } = this.intersection; n[Ze] ??= /* @__PURE__ */ new Map(), n[Ze].set(t.button, t.timeStamp), this.buttonsDownTime.set(t.button, t.timeStamp); } up(t) { if (this.buttonsDown.delete(t.button), !this.enabled) return; if (!this.wasMoved) { this.onFirstMove.push(this.up.bind(this, t)); return; } if (this.intersection == null) return; const { clickThesholdMs: n, contextMenuButton: r = 2, dblClickThresholdMs: o = 500, clickThresholdMs: i = n ?? 300 } = this.options; this.pointerCapture = void 0; const s = vs(this.buttonsDownTime, this.intersection.object[Ze], t.button, t.timeStamp, i), a = this.getCamera(); if (s && t.button === r && N(new L("contextmenu", !0, t, this, this.intersection, a)), N(new L("pointerup", !0, t, this, this.intersection, a)), !s || t.button === r) return; N(new L("click", !0, t, this, this.intersection, a)); const { object: u } = this.intersection, l = u[gs] ??= /* @__PURE__ */ new Map(), c = l.get(t.button); if (c == null || t.timeStamp - c > o) { l.set(t.button, t.timeStamp); return; } N(new L("dblclick", !0, t, this, this.intersection, a)), l.delete(t.button); } cancel(t) { if (this.enabled) { if (!this.wasMoved) { this.onFirstMove.push(this.cancel.bind(this, t)); return; } this.intersection != null && N(new L("pointercancel", !0, t, this, this.intersection, this.getCamera())); } } wheel(t, n, r = !1) { if (!this.enabled) return; if (!this.wasMoved && r) { this.onFirstMove.push(this.wheel.bind(this, t, n, r)); return; } r || (this.wheelIntersection = this.computeIntersection("wheel", t, n)); const o = r ? this.intersection : this.wheelIntersection; o != null && N(new Be(n, this, o, this.getCamera())); } emitWheel(t, n = !1) { if (!this.enabled) return; if (!this.wasMoved && n) { this.onFirstMove.push(this.emitWheel.bind(this, t, n)); return; } const r = n ? this.intersection : this.wheelIntersection; r != null && N(new Be(t, this, r, this.getCamera())); } exit(t) { this.wasMoved && (this.pointerCapture != null && (this.parentReleasePointerCapture?.(), this.pointerCapture = void 0), this.intersection = void 0, this.commit(t, !1)), this.onFirstMove.length = 0, this.wasMoved = !1; } } function jr(e, t, n, r) { if (e == null) return; const o = n.indexOf(e); o != -1 ? n.splice(o, 1) : r.push(e), t.push(e), jr(e.parent, t, n, r); } function vs(e, t, n, r, o) { if (t == null) return !1; const i = t.get(n); return !(i == null || r - i > o || i != e.get(n)); } const he = new wr(), Je = new wr(), an = new Y(), un = new Y(), ln = new Y(), et = new D(), ys = new Te(), Pe = new D(); function Cs(e, t, n) { Pe.copy(t).applyMatrix4(ys.copy(n.matrixWorld).invert()); const r = n.geometry.attributes.uv; if (r == null || !(r instanceof br)) return !1; let o; return bs(n, (i, s, a) => { n.getVertexPosition(i, he.a), n.getVertexPosition(s, he.b), n.getVertexPosition(a, he.c); const u = he.closestPointToPoint(Pe, et).distanceTo(Pe); o != null && u >= o || (o = u, Je.copy(he), an.fromBufferAttribute(r, i), un.fromBufferAttribute(r, s), ln.fromBufferAttribute(r, a)); }), o == null ? !1 : (Je.closestPointToPoint(Pe, et), Je.getInterpolation(et, an, un, ln, e), !0); } function bs(e, t) { const n = e.geometry.drawRange; if (e.geometry.index != null) { const s = e.geometry.index, a = Math.max(0, n.start), u = Math.min(s.count, n.start + n.count); for (let l = a; l < u; l += 3) t(s.getX(l), s.getX(l + 1), s.getX(l + 2)); return; } const r = e.geometry.attributes.position; if (r == null) return; const o = Math.max(0, n.start), i = Math.min(r.count, n.start + n.count); for (let s = o; s < i; s += 3) t(s, s + 1, s + 2); } new Te(); new zo(); new D(); new ze(); new st(); new Y(); new D(0, 0, 0), new D(0, 0, 1); const cn = new Te(), ws = new D(); new D(0, 0, -1); new ze(); const fn = new Y(), As = new D(); class Ts { prepareTransformation; options; raycaster = new $o(); cameraQuaternion = new at(); fromPosition = new D(); fromQuaternion = new at(); coords = new Y(); viewPlane = new ze(); intersects = []; pointerEventsOrders = []; constructor(t, n) { this.prepareTransformation = t, this.options = n; } isReady() { return !0; } intersectPointerCapture({ intersection: t, object: n }, r) { const o = t.details; if (o.type != "screen-ray") throw new Error(`unable to process a pointer capture of type "${t.details.type}" with a camera ray intersector`); if (!this.startIntersection(r)) return t; this.viewPlane.constant -= o.distanceViewPlane; const i = this.raycaster.ray.intersectPlane(this.viewPlane, new D()); if (i == null) return t; t.object.updateWorldMatrix(!0, !1), cs(this.viewPlane, t, t.object.matrixWorld); let s = t.uv; return t.object instanceof He && Cs(fn, i, t.object) && (s = fn.clone()), { ...t, details: { ...o, direction: this.raycaster.ray.direction.clone(), screenPoint: this.coords.clone() }, uv: s, object: n, point: i, pointOnFace: i, pointerPosition: this.raycaster.ray.origin.clone(), pointerQuaternion: this.cameraQuaternion.clone() }; } startIntersection(t) { const n = this.prepareTransformation(t, this.coords); return n == null ? !1 : (n.updateWorldMatrix(!0, !1), n.matrixWorld.decompose(this.fromPosition, this.fromQuaternion, ws), this.raycaster.setFromCamera(this.coords, n), this.viewPlane.setFromNormalAndCoplanarPoint(n.getWorldDirection(As), this.raycaster.ray.origin), !0); } executeIntersection(t, n) { const r = this.intersects.length; t.raycast(this.raycaster, this.intersects), ms(this.pointerEventsOrders, n, this.intersects.length - r); } finalizeIntersection(t) { const n = this.fromPosition.clone(), r = this.cameraQuaternion.clone(), o = this.raycaster.ray.direction.clone(), i = ps(this.intersects, this.pointerEventsOrders, this.options), s = i == null ? void 0 : this.intersects[i]; return this.intersects.length = 0, this.pointerEventsOrders.length = 0, s == null ? _s(t, this.raycaster.ray, (a, u) => ({ type: "screen-ray", distanceViewPlane: u, screenPoint: this.coords.clone(), direction: o }), n, r) : (s.object.updateWorldMatrix(!0, !1), cn.copy(s.object.matrixWorld).invert(), Object.assign(s, { details: { type: "screen-ray", distanceViewPlane: this.viewPlane.distanceToPoint(s.point), screenPoint: this.coords.clone(), direction: o }, pointOnFace: s.point, pointerPosition: n, pointerQuaternion: r, localPoint: s.point.clone().applyMatrix4(cn) })); } } new D(); new Y(); new Te(); new D(); new at(); new ze(); new Ko(); new D(); new D(); new D(); new D(1e-4, 1e-4, 1e-4); new Te(); let Os = 23412; function Ss() { return Os++; } function Ps(e, t, n) { if (!(t instanceof globalThis.MouseEvent)) return n.set(0, 0); const { width: r, height: o, top: i, left: s } = e.getBoundingClientRect(), a = t.clientX - s, u = t.clientY - i; return n.set(a / r * 2 - 1, -(u / o) * 2 + 1); } function Is(e, t, n, r) { return Ds( e, //backwards compatibility typeof t == "function" ? t : () => t, n, Ps.bind(null, e), e.setPointerCapture.bind(e), (o) => { e.hasPointerCapture(o) && e.releasePointerCapture(o); }, { pointerTypePrefix: "screen-", ...r } ); } function Ds(e, t, n, r, o, i, s = {}) { const a = s?.forwardPointerCapture ?? !0, u = /* @__PURE__ */ new Map(), l = s.pointerTypePrefix ?? "forward-", c = (O, T) => { let E = u.get(O.pointerId); return E != null || (E = new Es(Ss(), `${l}${O.pointerType}`, O.pointerState, new Ts((x, R) => (r(x, R), t()), s), t, void 0, a ? o.bind(null, O.pointerId) : void 0, a ? i.bind(null, O.pointerId) : void 0, s), T != "move" && T != "wheel" && (E.setIntersection(E.computeIntersection("pointer", n, O)), E.commit(O, !1)), u.set(O.pointerId, E)), E; }, f = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), d = [], _ = [], v = (O, T, E) => { switch (O) { case "move": E.move(n, T); return; case "wheel": E.wheel(n, T); return; case "cancel": E.cancel(T); return; case "down": if (!dn(T)) return; E.down(T); return; case "up": if (!dn(T)) return; E.up(T); return; case "exit": h.delete(E), f.delete(E), E.exit(T); return; } }, p = (O, T) => { const E = c(T, O); O === "move" && h.set(E, T), O === "wheel" && f.set(E, T), s.batchEvents ?? !0 ? _.push({ type: O, event: T }) : v(O, T, E); }, g = p.bind(null, "move"), C = p.bind(null, "cancel"), b = p.bind(null, "down"), P = p.bind(null, "up"), M = p.bind(null, "wheel"), A = p.bind(null, "exit"); return e.addEventListener("pointermove", g), e.addEventListener("pointercancel", C), e.addEventListener("pointerdown", b), e.addEventListener("pointerup", P), e.addEventListener("wheel", M), e.addEventListener("pointerleave", A), { destroy() { e.removeEventListener("pointermove", g), e.removeEventListener("pointercancel", C), e.removeEventListener("pointerdown", b), e.removeEventListener("pointerup", P), e.removeEventListener("wheel", M), e.removeEventListener("pointerleave", A), h.clear(), f.clear(); }, update() { const O = _.length; for (let T = 0; T < O; T++) { const { type: E, event: x } = _[T], R = c(x, E); if (E === "move" && (d.push(R), h.get(R) != x)) { R.emitMove(x); continue; } if (E === "wheel" && f.get(R) != x) { R.emitWheel(x); continue; } v(E, x, R); } if (_.length = 0, s.intersectEveryFrame ?? !1) for (const [T, E] of h.entries()) d.includes(T) || T.move(n, E); d.length = 0; } }; } function dn(e) { return e.button != null; } function ks({ canvas: e, contextParts: { scene: t, camera: n, renderer: r } }) { const { update: o, destroy: i } = Is(I(e), () => I(n.activeCamera), t.value), { off: s } = r.loop.onLoop(o); ie(i), ie(s); const a = Ur(t.value), u = Ee(); return a.addEventListener("click", u.trigger), { onPointerMissed: u.on }; } const xs = "useTres", [Rs, Ls] = fi(({ scene: e, canvas: t, windowSize: n, rendererOptions: r }) => { const o = it(e), i = os(n, t), s = Ji({ sizes: i }), a = rs( { scene: o, canvas: t, options: r, contextParts: { sizes: i, camera: s } } ), u = ks({ canvas: t, contextParts: { scene: o, camera: s, renderer: a } }), l = { sizes: i, scene: o, camera: s, renderer: a, controls: Ae(null), extend: pt, events: u }; return l.scene.value.__tres = { root: l }, l; }, { injectionKey: "useTres" }), zr = () => { const e = Ls(); if (!e) throw new Error(`useTresContext must be used together with useTresContextProvider. You probably tried to use it above or on the same level as a TresCanvas component. It should be used in child components of a TresCanvas instance.`); return e; }; function Fs() { const { scene: e, renderer: t, camera: n, sizes: r, controls: o, extend: i, events: s } = zr(); return { scene: e, renderer: t.instance, camera: n.activeCamera, sizes: r, controls: o, extend: i, events: s, invalidate: t.invalidate, advance: t.advance }; } const _l = () => { const e = Fs(), { renderer: t } = zr(), n = nn(), r = nn(); t.loop.onBeforeLoop((i) => { n.trigger({ ...e, ...i }); }), t.loop.onLoop((i) => { r.trigger({ ...e, ...i }); }); const o = t.replaceRenderFunction; return { stop: t.loop.stop, start: t.loop.start, isActive: t.loop.isActive, onBeforeRender: n.on, onRender: r.on, render: o }; }; function Ms(e, t = {}, n = {}) { let r = e; const o = (a) => { r = a; }; let i = new Proxy({}, {}); const s = { has(a, u) { return u in t || u in r; }, get(a, u, l) { return u in t ? t[u](r) : r[u]; }, set(a, u, l) { return n[u] ? n[u](l, r, i, o) : r[u] = l, !0; } }; return i = new Proxy({}, s), i; } const Ns = [ "onClick", "onContextmenu", "onPointermove", "onPointerenter", "onPointerleave", "onPointerover", "onPointerout", "onDblclick", "onPointerdown", "onPointerup", "onPointercancel", "onLostpointercapture", "onWheel" ], Vs = { onClick: "click", onContextmenu: "contextmenu", onPointermove: "pointermove", onPointerenter: "pointerenter", onPointerleave: "pointerleave", onPointerover: "pointerover", onPointerout: "pointerout", onDblclick: "dblclick", onPointerdown: "pointerdown", onPointerup: "pointerup", onPointercancel: "pointercancel", onLostpointercapture: "lostpointercapture", onWheel: "wheel" }, pn = (e) => Ns.includes(e), Bs = (e) => { const t = e.scene.value; function n(c, f, h, d) { if (d || (d = {}), d.args || (d.args = []), Vi(c)) return null; c.includes("-") && (c = c.replace(/-([a-z])/g, (p, g) => g.toUpperCase()).replace(/^[a-z]/, (p) => p.toUpperCase())); let _ = c.replace("Tres", ""), v; if (c === "primitive") { (!Tt(d.object) || me(d.object)) && Jt( "Tres primitives need an 'object' prop, whose value is an object or shallowRef<object>" ), _ = d.object.type; const p = {}; v = Ms( d.object, { object: (C) => C, isPrimitive: () => !0, __tres: () => p }, { object: (C, b, P, M) => { Qi(C, P, M, { patchProp: i, remove: o, insert: r }, e); }, __tres: (C) => { Object.assign(p, C); } } ); } else { const p = dt.value[_]; p || Jt( `${_} is not defined on the THREE namespace. Use extend to add it to the catalog.` ), v = new p(...d.args); } return v ? (re(v) && (d?.position || v.position.set(3, 3, 3), d?.lookAt || v.lookAt(0, 0, 0)), v = X(v, { ...Gi(v) ? v.__tres : {}, type: _, memoizedProps: d, primitive: c === "primitive", attach: d.attach }, e), v) : null; } function r(c, f) { if (!c) return; f = f || t; const h = c.__tres ? c : X(c, {}, e), d = f.__tres ? f : X(f, {}, e); c = se(h), f = se(d), re(c) && e.camera?.registerCamera(c), h.__tres.attach ? qi(d, h, h.__tres.attach) : lt(c) && lt(d) && (d.add(c), c.dispatchEvent({ type: "added" })), h.__tres.parent = d, d.__tres.objects && !d.__tres.objects.includes(h) && d.__tres.objects.push(h); } function o(c, f) { if (!c) return; f = ut(f) ? "default" : f; const h = c.__tres?.dispose; ut(h) || (h === null ? f = !1 : f = h); const d = c.__tres?.primitive, _ = f === "default" ? !d : !!f; if (c.__tres && "objects" in c.__tres && [...c.__tres.objects].forEach((v) => o(v, f)), _ && c.children && [...c.children].forEach((v) => o(v, f)), Mr(c, e), Nr(c, e), _ && !Fr(c)) { if (Q(f)) f(c); else if (Q(c.dispose)) try { c.dispose(); } catch { } } "__tres" in c && delete c.__tres; } function i(c, f, h, d) { if (!c) return; let _ = c; const v = f; if (c.__tres && (c.__tres.memoizedProps[f] = d), f === "attach") { const b = c.__tres?.parent || c.parent; o(c), X(c, { attach: d }, e), b && r(c, b); return; } if (f === "dispose") { c.__tres || (c = X(c, {}, e)), c.__tres.dispose = d; return; } pn(f) && Q(d) && c.addEventListener(Vs[f], d); let p = Qt(v), g = _?.[p]; if (v === "args") { const b = c, P = h ?? [], M = d ?? [], A = c.__tres?.type || c.type; if (A && P.length && !Or(P, M)) { const O = new dt.value[A](...d), T = Object.getOwnPropertyDescriptors(O); Object.entries(T).forEach(([E, x]) => { if (!(!x.writable && !x.set) && E in b) try { b[E] = O[E]; } catch (R) { console.warn(`Could not set property ${E} on ${A}:`, R); } }), _ = b; } return; } if (_.type === "BufferGeometry") { if (v === "args") return; _.setAttribute( Qt(v), new br(...d) ); return; } if (v.includes("-") && g === void 0) { const b = Ve(_, v); if (g = b.target, _ = b.target, p = b.key, g && p) { g[p] = d, re(c) && c.updateProjectionMatrix(), ft(c); return;