lunchboxjs 0.1.4002 → 0.1.4006

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -0,0 +1,3 @@
1
+ Custom Vue 3 renderer for ThreeJS.
2
+
3
+ [Docs](//docs.lunchboxjs.com)
@@ -30,27 +30,36 @@
30
30
  const resizeCanvas = (width, height) => {
31
31
  const renderer = ensureRenderer.value?.instance;
32
32
  const scene = ensuredScene.value.instance;
33
+ const camera = ensuredCamera.value;
33
34
  // ignore if no element
34
- if (!renderer?.domElement || !scene)
35
+ if (!renderer?.domElement || !scene || !camera)
35
36
  return;
36
37
  width = width ?? window.innerWidth;
37
38
  height = height ?? window.innerHeight;
38
39
  // update camera
39
40
  const aspect = width / height;
40
- const camera = ensuredCamera.value;
41
41
  if (camera.type?.toLowerCase() === 'perspectivecamera') {
42
42
  const perspectiveCamera = camera.instance;
43
43
  perspectiveCamera.aspect = aspect;
44
44
  perspectiveCamera.updateProjectionMatrix();
45
45
  }
46
+ else if (camera.type?.toLowerCase() === 'orthographiccamera') {
47
+ // console.log('TODO: ortho camera update')
48
+ const orthoCamera = camera.instance;
49
+ const heightInTermsOfWidth = height / width;
50
+ orthoCamera.top = heightInTermsOfWidth * 10;
51
+ orthoCamera.bottom = -heightInTermsOfWidth * 10;
52
+ orthoCamera.right = 10;
53
+ orthoCamera.left = -10;
54
+ orthoCamera.updateProjectionMatrix();
55
+ }
46
56
  else {
47
- console.log('TODO: ortho camera update');
57
+ console.log('TODO: non-ortho or perspective camera');
48
58
  }
49
59
  // update canvas
50
60
  renderer.setSize(width, height);
51
61
  // render immediately so there's no flicker
52
62
  if (scene && camera.instance) {
53
- // const cameraInstance = scene.traverse(v => )
54
63
  renderer.render(vue.toRaw(scene), vue.toRaw(camera.instance));
55
64
  }
56
65
  };
@@ -95,8 +104,13 @@
95
104
  props: {
96
105
  // These should match the Lunchbox.WrapperProps interface
97
106
  background: String,
107
+ cameraArgs: Array,
108
+ cameraLook: Array,
109
+ cameraLookAt: Array,
98
110
  cameraPosition: Array,
99
111
  dpr: Number,
112
+ ortho: Boolean,
113
+ orthographic: Boolean,
100
114
  rendererProperties: Object,
101
115
  shadow: [Boolean, Object],
102
116
  transparent: Boolean,
@@ -107,6 +121,7 @@
107
121
  const dpr = vue.ref(props.dpr ?? -1);
108
122
  const container = vue.ref();
109
123
  let renderer;
124
+ let camera;
110
125
  let scene;
111
126
  // MOUNT
112
127
  // ====================
@@ -114,12 +129,6 @@
114
129
  // canvas needs to exist
115
130
  if (!canvas.value)
116
131
  throw new Error('missing canvas');
117
- // ensure camera
118
- const camera = ensuredCamera.value.instance;
119
- // move camera if needed
120
- if (camera && props.cameraPosition) {
121
- camera.position.set(...props.cameraPosition);
122
- }
123
132
  // RENDERER
124
133
  // ====================
125
134
  // is there already a renderer?
@@ -176,6 +185,47 @@
176
185
  rendererReady.value = true;
177
186
  return;
178
187
  }
188
+ // CAMERA
189
+ // ====================
190
+ // is there already a camera?
191
+ camera = tryGetNodeWithInstanceType([
192
+ 'PerspectiveCamera',
193
+ 'OrthographicCamera',
194
+ ]);
195
+ // if not, let's create one
196
+ if (!camera) {
197
+ // create ortho camera
198
+ if (props.ortho || props.orthographic) {
199
+ ensuredCamera.value = createNode({
200
+ props: { args: props.cameraArgs ?? [] },
201
+ type: 'OrthographicCamera',
202
+ uuid: fallbackCameraUuid,
203
+ });
204
+ }
205
+ else {
206
+ ensuredCamera.value = createNode({
207
+ props: {
208
+ args: props.cameraArgs ?? [45, 0.5625, 1, 1000],
209
+ },
210
+ type: 'PerspectiveCamera',
211
+ uuid: fallbackCameraUuid,
212
+ });
213
+ }
214
+ cameraReady.value = true;
215
+ camera = ensuredCamera.value;
216
+ }
217
+ else {
218
+ cameraReady.value = true;
219
+ }
220
+ // move camera if needed
221
+ if (camera && props.cameraPosition) {
222
+ camera.instance?.position.set(...props.cameraPosition);
223
+ }
224
+ // angle camera if needed
225
+ if (camera && (props.cameraLookAt || props.cameraLook)) {
226
+ const source = (props.cameraLookAt || props.cameraLook);
227
+ camera.instance?.lookAt(...source);
228
+ }
179
229
  // SCENE
180
230
  // ====================
181
231
  scene = ensuredScene.value;
@@ -202,7 +252,7 @@
202
252
  // console.log(scene)
203
253
  update({
204
254
  app: vue.getCurrentInstance().appContext.app,
205
- camera,
255
+ camera: camera.instance,
206
256
  renderer: renderer.instance,
207
257
  scene: scene.instance,
208
258
  });
@@ -232,21 +282,6 @@
232
282
  },
233
283
  };
234
284
 
235
- const catalogue = {};
236
-
237
- const lunchboxDomComponentNames = [
238
- 'canvas',
239
- 'div',
240
- 'LunchboxWrapper',
241
- ];
242
- // component creation utility
243
- const createComponent$1 = (tag) => vue.defineComponent({
244
- inheritAttrs: false,
245
- name: tag,
246
- setup(props, context) {
247
- return () => vue.h(tag, context.attrs, context.slots?.default?.() || []);
248
- },
249
- });
250
285
  // list of all components to register out of the box
251
286
  const autoGeneratedComponents = [
252
287
  // ThreeJS basics
@@ -359,21 +394,11 @@
359
394
  'arrayCamera',
360
395
  // renderers
361
396
  'webGLRenderer',
362
- ].map(createComponent$1).reduce((acc, curr) => {
363
- acc[curr.name] = curr;
364
- return acc;
365
- });
366
- const components = {
367
- ...autoGeneratedComponents,
368
- 'Lunchbox': LunchboxWrapper,
369
- // Gltf,
370
- };
371
- // console.log(components, Gltf)
372
- /*
373
- // List copied from r3f
374
- // https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
397
+ /*
398
+ // List copied from r3f:
399
+ // https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
375
400
 
376
- // NOT IMPLEMENTED:
401
+ // NOT IMPLEMENTED (can be added via Extend - docs.lunchboxjs.com/components/extend/):
377
402
  audioListener: AudioListenerProps
378
403
  positionalAudio: PositionalAudioProps
379
404
 
@@ -421,6 +446,27 @@
421
446
  fogExp2: FogExp2Props
422
447
  shape: ShapeProps
423
448
  */
449
+ ];
450
+
451
+ const catalogue = {};
452
+
453
+ const lunchboxDomComponentNames = ['canvas', 'div', 'LunchboxWrapper'];
454
+ // component creation utility
455
+ const createComponent$1 = (tag) => vue.defineComponent({
456
+ inheritAttrs: false,
457
+ name: tag,
458
+ setup(props, context) {
459
+ return () => vue.h(tag, context.attrs, context.slots?.default?.() || []);
460
+ },
461
+ });
462
+ autoGeneratedComponents.map(createComponent$1).reduce((acc, curr) => {
463
+ acc[curr.name] = curr;
464
+ return acc;
465
+ });
466
+ const components = {
467
+ ...autoGeneratedComponents,
468
+ Lunchbox: LunchboxWrapper,
469
+ };
424
470
 
425
471
  function find(target) {
426
472
  target = vue.isRef(target) ? target.value : target;
@@ -582,6 +628,7 @@
582
628
  // register click, pointerdown, pointerup
583
629
  if (key === 'onClick' || key === 'onPointerDown' || key === 'onPointerUp') {
584
630
  const stop = vue.watch(() => inputActive.value, (isDown) => {
631
+ console.log(isDown, currentIntersections);
585
632
  const idx = currentIntersections
586
633
  .map((v) => v.element)
587
634
  .findIndex((v) => v.instance &&
@@ -849,9 +896,27 @@
849
896
  // ENSURE CAMERA
850
897
  // ====================
851
898
  const fallbackCameraUuid = 'FALLBACK_CAMERA';
852
- const ensuredCamera = buildEnsured(['PerspectiveCamera', 'OrthographicCamera'], fallbackCameraUuid, {
853
- args: [45, 0.5625, 1, 1000],
899
+ const defaultCamera = buildEnsured(['PerspectiveCamera', 'OrthographicCamera'], fallbackCameraUuid, { args: [45, 0.5625, 1, 1000] });
900
+ /** Special value to be changed ONLY in `LunchboxWrapper`.
901
+ * Functions waiting for a Camera need to wait for this to be true. */
902
+ const cameraReady = vue.ref(false);
903
+ const ensuredCamera = vue.computed({
904
+ get() {
905
+ return (cameraReady.value ? defaultCamera.value : null);
906
+ },
907
+ set(val) {
908
+ const t = val.type ?? '';
909
+ const pascalType = t[0].toUpperCase() + t.slice(1);
910
+ overrides[pascalType] = val;
911
+ },
854
912
  });
913
+ // export const ensuredCamera = buildEnsured<THREE.Camera>(
914
+ // ['PerspectiveCamera', 'OrthographicCamera'],
915
+ // fallbackCameraUuid,
916
+ // {
917
+ // args: [45, 0.5625, 1, 1000],
918
+ // }
919
+ // )
855
920
  // ENSURE RENDERER
856
921
  // ====================
857
922
  const fallbackRendererUuid = 'FALLBACK_RENDERER';
@@ -1200,12 +1265,14 @@
1200
1265
  const beforeRender = [];
1201
1266
  const afterRender = [];
1202
1267
  const update = (opts) => {
1268
+ // request next frame
1203
1269
  frameID = requestAnimationFrame(() => update({
1204
1270
  app: opts.app,
1205
1271
  renderer: ensureRenderer.value?.instance,
1206
1272
  scene: ensuredScene.value.instance,
1207
- camera: ensuredCamera.value.instance,
1273
+ camera: ensuredCamera.value?.instance,
1208
1274
  }));
1275
+ // prep options
1209
1276
  const { app, renderer, scene, camera } = opts;
1210
1277
  // BEFORE RENDER
1211
1278
  beforeRender.forEach((cb) => {
@@ -1214,9 +1281,13 @@
1214
1281
  }
1215
1282
  });
1216
1283
  // RENDER
1217
- // console.log(camera?.position.z)
1218
1284
  if (renderer && scene && camera) {
1219
- renderer.render(vue.toRaw(scene), vue.toRaw(camera));
1285
+ if (app.customRender) {
1286
+ app.customRender(opts);
1287
+ }
1288
+ else {
1289
+ renderer.render(vue.toRaw(scene), vue.toRaw(camera));
1290
+ }
1220
1291
  }
1221
1292
  // AFTER RENDER
1222
1293
  afterRender.forEach((cb) => {
@@ -1233,6 +1304,15 @@
1233
1304
  beforeRender.splice(index, 0, cb);
1234
1305
  }
1235
1306
  };
1307
+ const offBeforeRender = (cb) => {
1308
+ if (isFinite(cb)) {
1309
+ beforeRender.splice(cb, 1);
1310
+ }
1311
+ else {
1312
+ const idx = beforeRender.findIndex((v) => v == cb);
1313
+ beforeRender.splice(idx, 1);
1314
+ }
1315
+ };
1236
1316
  const onAfterRender = (cb, index = Infinity) => {
1237
1317
  if (index === Infinity) {
1238
1318
  afterRender.push(cb);
@@ -1241,6 +1321,15 @@
1241
1321
  afterRender.splice(index, 0, cb);
1242
1322
  }
1243
1323
  };
1324
+ const offAfterRender = (cb) => {
1325
+ if (isFinite(cb)) {
1326
+ afterRender.splice(cb, 1);
1327
+ }
1328
+ else {
1329
+ const idx = afterRender.findIndex((v) => v == cb);
1330
+ afterRender.splice(idx, 1);
1331
+ }
1332
+ };
1244
1333
  const cancelUpdate = () => {
1245
1334
  if (frameID)
1246
1335
  cancelAnimationFrame(frameID);
@@ -1594,11 +1683,33 @@
1594
1683
  inputActive,
1595
1684
  mousePos,
1596
1685
  };
1597
- const camera = vue.computed(() => ensuredCamera.value.instance);
1686
+ const camera = vue.computed(() => ensuredCamera.value?.instance ?? null);
1598
1687
  const renderer = vue.computed(() => ensureRenderer.value?.instance ?? null);
1599
1688
  const scene = vue.computed(() => ensuredScene.value.instance);
1689
+ // CUSTOM RENDER SUPPORT
1690
+ // ====================
1691
+ let app = null;
1692
+ let queuedCustomRenderFunction = null;
1693
+ /** Set a custom render function, overriding the Lunchbox app's default render function.
1694
+ * Changing this requires the user to manually render their scene.
1695
+ */
1696
+ const setCustomRender = (render) => {
1697
+ if (app)
1698
+ app.setCustomRender(render);
1699
+ else
1700
+ queuedCustomRenderFunction = render;
1701
+ };
1702
+ /** Clear the active app's custom render function. */
1703
+ const clearCustomRender = () => {
1704
+ if (app)
1705
+ app.clearCustomRender();
1706
+ else
1707
+ queuedCustomRenderFunction = null;
1708
+ };
1709
+ // CREATE APP
1710
+ // ====================
1600
1711
  const createApp = (root) => {
1601
- const app = vue.createRenderer(nodeOps).createApp(root);
1712
+ app = vue.createRenderer(nodeOps).createApp(root);
1602
1713
  // register all components
1603
1714
  Object.keys(components).forEach((key) => {
1604
1715
  app.component(key, components[key]);
@@ -1621,22 +1732,38 @@
1621
1732
  };
1622
1733
  // embed .extend function
1623
1734
  app.extend = (targets) => {
1624
- extend({ app, ...targets });
1735
+ extend({ app: app, ...targets });
1625
1736
  return app;
1626
1737
  };
1738
+ // prep for custom render support
1739
+ app.setCustomRender = (newRender) => {
1740
+ app.customRender = newRender;
1741
+ };
1742
+ // add queued custom render if we have one
1743
+ if (queuedCustomRenderFunction) {
1744
+ app.setCustomRender(queuedCustomRenderFunction);
1745
+ queuedCustomRenderFunction = null;
1746
+ }
1747
+ // add custom render removal
1748
+ app.clearCustomRender = () => {
1749
+ app.customRender = null;
1750
+ };
1627
1751
  // done
1628
1752
  return app;
1629
1753
  };
1630
1754
 
1631
1755
  exports.camera = camera;
1756
+ exports.clearCustomRender = clearCustomRender;
1632
1757
  exports.createApp = createApp;
1633
1758
  exports.find = find;
1634
1759
  exports.globals = globals;
1760
+ exports.offAfterRender = offAfterRender;
1761
+ exports.offBeforeRender = offBeforeRender;
1635
1762
  exports.onAfterRender = onAfterRender;
1636
1763
  exports.onBeforeRender = onBeforeRender;
1637
1764
  exports.renderer = renderer;
1638
1765
  exports.scene = scene;
1639
- exports.update = update;
1766
+ exports.setCustomRender = setCustomRender;
1640
1767
 
1641
1768
  Object.defineProperty(exports, '__esModule', { value: true });
1642
1769
 
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("three"),require("lodash")):"function"==typeof define&&define.amd?define(["exports","vue","three","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LunchboxRenderer={},e.vue,e.three,e.lodash)}(this,(function(e,t,n,r){"use strict";function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var a=o(n);const s=[],i=(e,n)=>{const r=$.value?.instance,o=U.value.instance;if(!r?.domElement||!o)return;const a=(e=e??window.innerWidth)/(n=n??window.innerHeight),s=k.value;if("perspectivecamera"===s.type?.toLowerCase()){const e=s.instance;e.aspect=a,e.updateProjectionMatrix()}else console.log("TODO: ortho camera update");r.setSize(e,n),o&&s.instance&&r.render(t.toRaw(o),t.toRaw(s.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraPosition:Array,dpr:Number,rendererProperties:Object,shadow:[Boolean,Object],transparent:Boolean},setup(e,o){const a=t.ref(),s=t.ref(!0),d=t.ref(e.dpr??-1),u=t.ref();let l,p;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");const o=k.value.instance;if(o&&e.cameraPosition&&o.position.set(...e.cameraPosition),l=B(["WebGLRenderer"]),l)return s.value=!1,void(F.value=!0);{const t={antialias:!0,canvas:a.value.domElement};e.transparent&&(t.alpha=!0),$.value=v({type:"WebGLRenderer",uuid:S,props:{args:[t]}}),F.value=!0;const n=$,o={shadow:e.shadow};n.value.instance&&o?.shadow&&(n.value.instance.shadowMap.enabled=!0,"object"==typeof o.shadow&&(n.value.instance.shadowMap.type=o.shadow.type)),e.rendererProperties&&Object.keys(e.rendererProperties).forEach((t=>{r.set(n.value,t,e.rendererProperties[t])})),l=n.value}if(p=U.value,p&&p.instance&&e.background&&(p.instance.background=new n.Color(e.background)),-1===d.value&&(d.value=window.devicePixelRatio),!l?.instance)throw new Error("missing renderer");l.instance.setPixelRatio(d.value),ue.dpr.value=d.value,((e,t,n)=>{const r=e.value?.domElement;if(!r)throw new Error("missing container");i();const o=new ResizeObserver((([e])=>{i()}));r&&o.observe(r),n((()=>{t&&o.unobserve(t)}))})(u,l.instance.domElement,t.onBeforeUnmount),te({app:t.getCurrentInstance().appContext.app,camera:o,renderer:l.instance,scene:p.instance})})),t.onBeforeUnmount((()=>{re()})),()=>[o.slots.default?.()??null,t.h("div",{style:c("absolute"),ref:u},[s.value?t.h("canvas",{style:c("fixed"),class:"lunchbox-canvas",ref:a}):null])]}},u={},l=["canvas","div","LunchboxWrapper"],p={...["mesh","instancedMesh","scene","sprite","object3D","instancedBufferGeometry","bufferGeometry","boxBufferGeometry","circleBufferGeometry","coneBufferGeometry","cylinderBufferGeometry","dodecahedronBufferGeometry","extrudeBufferGeometry","icosahedronBufferGeometry","latheBufferGeometry","octahedronBufferGeometry","parametricBufferGeometry","planeBufferGeometry","polyhedronBufferGeometry","ringBufferGeometry","shapeBufferGeometry","sphereBufferGeometry","tetrahedronBufferGeometry","textBufferGeometry","torusBufferGeometry","torusKnotBufferGeometry","tubeBufferGeometry","wireframeGeometry","parametricGeometry","tetrahedronGeometry","octahedronGeometry","icosahedronGeometry","dodecahedronGeometry","polyhedronGeometry","tubeGeometry","torusKnotGeometry","torusGeometry","sphereGeometry","ringGeometry","planeGeometry","latheGeometry","shapeGeometry","extrudeGeometry","edgesGeometry","coneGeometry","cylinderGeometry","circleGeometry","boxGeometry","material","shadowMaterial","spriteMaterial","rawShaderMaterial","shaderMaterial","pointsMaterial","meshPhysicalMaterial","meshStandardMaterial","meshPhongMaterial","meshToonMaterial","meshNormalMaterial","meshLambertMaterial","meshDepthMaterial","meshDistanceMaterial","meshBasicMaterial","meshMatcapMaterial","lineDashedMaterial","lineBasicMaterial","light","spotLightShadow","spotLight","pointLight","rectAreaLight","hemisphereLight","directionalLightShadow","directionalLight","ambientLight","lightShadow","ambientLightProbe","hemisphereLightProbe","lightProbe","texture","videoTexture","dataTexture","dataTexture3D","compressedTexture","cubeTexture","canvasTexture","depthTexture","textureLoader","group","catmullRomCurve3","points","cameraHelper","camera","perspectiveCamera","orthographicCamera","cubeCamera","arrayCamera","webGLRenderer"].map((e=>t.defineComponent({inheritAttrs:!1,name:e,setup:(n,r)=>()=>t.h(e,r.attrs,r.slots?.default?.()||[])}))).reduce(((e,t)=>(e[t.name]=t,e))),Lunchbox:d};const h=e=>e?.$el&&e?.$el?.hasOwnProperty?.("instance"),m=e=>{if("domMeta"===e?.metaType)return!0;const t="string"==typeof e?e:e?.type;return l.includes(t??"")},f=e=>"standardMeta"===e?.metaType,y=e=>e.isLunchboxRootNode;function v(e={},t={}){const n={attached:e.attached??[],attachedArray:e.attachedArray??{},instance:e.instance??null},r=new H.RendererStandardNode({...e,...n,metaType:"standardMeta"});return!r.type||y(r)||r.instance||(r.instance=function(e){if(!e.type)return null;const t=e.type[0].toUpperCase()+e.type.slice(1),n=u[e.type]||a[t];if(!n)throw`${t} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`;const r=(e.props.args??[]).map((t=>function({node:e,prop:t}){const n="string"==typeof t&&t.startsWith("$attachedArray"),r=function({node:e,prop:t}){if("string"==typeof t&&t.startsWith("$attachedArray"))return e.attachedArray[t.replace("$attachedArray.","")];if("string"==typeof t&&t.startsWith("$attached"))return e.attached[t.replace("$attached.","")];return t}({node:e,prop:t});return Array.isArray(r)&&n?r:[r]}({node:e,prop:t})));let o=[];r.forEach((e=>{o=o.concat(e)}));return new n(...o)}({...r,props:{...r.props,...t}})),"scene"===r.type&&(U.value=r),r}const b=[],x=t.ref(!1);function g({node:e,key:n,value:r}){var o;if(e.eventListeners[n]||(e.eventListeners[n]=[]),e.eventListenerRemoveFunctions[n]||(e.eventListenerRemoveFunctions[n]=[]),e.eventListeners[n].push(r),w.includes(n)&&(W.value,e.instance&&!b.includes(e)&&(o=e,b.push(o),e.eventListenerRemoveFunctions[n].push((()=>(e=>{const t=b.indexOf(e);-1!==t&&b.splice(t,1)})(e))))),"onClick"===n||"onPointerDown"===n||"onPointerUp"===n){const r=t.watch((()=>x.value),(t=>{const r=P.map((e=>e.element)).findIndex((t=>t.instance&&t.instance.uuid===e.instance?.uuid));-1!==r&&((!t||"onClick"!==n&&"onPointerDown"!==n)&&(t||"onPointerUp"!==n)||e.eventListeners[n].forEach((e=>{e({intersection:P[r].intersection})})))}));e.eventListenerRemoveFunctions[n].push(r)}return e}const w=["onClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove"];let E,R,A;const L=t.ref({x:1/0,y:1/0});let C=!1;let P=[];const M=()=>{const e=W.value?.instance,t=k.value?.instance;if(!e||!t)return;e.setFromCamera(ue.mousePos.value,t);const n=e.intersectObjects(b.map((e=>e.instance)));let r=[],o=[],a=[];r=P.map((e=>e.intersection)),n?.forEach((e=>{const t=P.findIndex((t=>t.intersection.object===e.object));if(-1===t){const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&o.push({element:t,intersection:e})}else{const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&a.push({element:t,intersection:e})}const n=r.findIndex((t=>t.object.uuid===e.object.uuid));-1!==n&&r.splice(n,1)}));const s=r.map((e=>({element:b.find((t=>t.instance?.uuid===e.object.uuid)),intersection:e})));o.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerEnter"],intersection:t})})),a.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerOver","onPointerMove"],intersection:t})})),s.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerLeave","onPointerOut"],intersection:t})})),P=[].concat(o,a)},G=({element:e,eventKeys:t,intersection:n})=>{e&&t.forEach((t=>{e.eventListeners[t]&&e.eventListeners[t].forEach((e=>{e({intersection:n})}))}))};function N(t={}){return e.lunchboxTree||(e.lunchboxTree=new H.RendererRootNode(t)),e.lunchboxTree}function B(e){Array.isArray(e)||(e=[e]);for(let t of e)if(O[t])return O[t];for(let t of e){const e=T[t]||s.find((e=>e.type?.toLowerCase()===t.toLowerCase()));if(e){const n=e;return T[t]=n,n}}return null}e.lunchboxTree=void 0;const T=t.reactive({}),O=t.reactive({});function j(e,n,r={},o=null){Array.isArray(e)||(e=[e]);for(let t of e)T[t]||(T[t]=null),O[t]||(O[t]=null);return t.computed({get(){const t=B(e);if(t)return t;const a=N(),s=v({type:e[0],uuid:n,props:r});return a.addChild(s),T[e[0]]=s,o&&o(s),s},set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}})}const k=j(["PerspectiveCamera","OrthographicCamera"],"FALLBACK_CAMERA",{args:[45,.5625,1,1e3]}),S="FALLBACK_RENDERER",D=j(["WebGLRenderer"],S,{}),F=t.ref(!1),$=t.computed({get:()=>F.value?D.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}}),U=j("Scene","FALLBACK_SCENE"),W=j("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>$.value),(e=>{e?.instance&&(C||(E=t=>{const n=(e.instance.domElement.width??1)/ue.dpr.value,r=(e.instance.domElement.height??1)/ue.dpr.value;L.value.x=t.offsetX/n*2-1,L.value.y=-t.offsetY/r*2+1},R=()=>x.value=!0,A=()=>x.value=!1,e.instance.domElement.addEventListener("mousemove",E),e.instance.domElement.addEventListener("mousedown",R),e.instance.domElement.addEventListener("mouseup",A),ne(M),C=!0),n&&n())}),{immediate:!0})})(e))),I=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var K,_=new Uint8Array(16);function V(){if(!K&&!(K="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return K(_)}var q=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function z(e){return"string"==typeof e&&q.test(e)}for(var H,Y=[],X=0;X<256;++X)Y.push((X+256).toString(16).substr(1));function J(e,t,n){var r=(e=e||{}).random||(e.rng||V)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(var o=0;o<16;++o)t[n+o]=r[o];return t}return function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(Y[e[t+0]]+Y[e[t+1]]+Y[e[t+2]]+Y[e[t+3]]+"-"+Y[e[t+4]]+Y[e[t+5]]+"-"+Y[e[t+6]]+Y[e[t+7]]+"-"+Y[e[t+8]]+Y[e[t+9]]+"-"+Y[e[t+10]]+Y[e[t+11]]+Y[e[t+12]]+Y[e[t+13]]+Y[e[t+14]]+Y[e[t+15]]).toLowerCase();if(!z(n))throw TypeError("Stringified UUID is invalid");return n}(r)}!function(e){e.BaseNode=class{constructor(e={},t){this.parentNode=e?.parentNode??t??null,this.minidomType="MinidomBaseNode",this.uuid=e?.uuid??J(),s.push(this)}uuid;parentNode;get nextSibling(){if(!this.parentNode)return null;const e=this.parentNode.children.findIndex((e=>e.uuid===this.uuid));return-1!==e&&e<this.parentNode.children.length-1?this.parentNode.children[e+1]:null}insertBefore(e,t){e.removeAsChildFromAnyParents(),e.parentNode=this;const n=this.children.findIndex((e=>e.uuid===t?.uuid));-1!==n?this.children.splice(n,0,e):this.children.push(e)}removeChild(e){const t=this.children.findIndex((t=>t?.uuid===e?.uuid));-1!==t&&this.children.splice(t,1)}children=[];addChild(e){return e&&(e.removeAsChildFromAnyParents(),e.parentNode=this,this.insertBefore(e,null)),this}getPath(){const e=[];let t=this;for(;t;)e.unshift(t),t=t.parentNode;return e}drop(){this.parentNode=null,this.removeAsChildFromAnyParents()}walk(e){const t=[this,...this.children],n=[];let r=!0;for(;t.length&&r;){const o=t.shift();if(o){if(n.includes(o))continue;n.push(o),t.push(...o.children.filter((e=>!n.includes(e)))),r=e(o)}else r=!1}}minidomType;removeAsChildFromAnyParents(){s.forEach((e=>e.removeChild(this)))}};class t extends e.BaseNode{constructor(e={},t){super(e,t),this.minidomType="RendererNode",this.eventListeners={},this.eventListenerRemoveFunctions={},this.name=e.name??"",this.metaType=e.metaType??"standardMeta",this.props=e.props??[],this.type=e.type??""}eventListeners;eventListenerRemoveFunctions;name;metaType;props;type;drop(){super.drop(),Object.keys(this.eventListenerRemoveFunctions).forEach((e=>{this.eventListenerRemoveFunctions[e].forEach((e=>e()))}))}}e.RendererBaseNode=t;class n extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement;isLunchboxRootNode=!0}e.RendererRootNode=n;class r extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererCommentNode=r;class o extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement}e.RendererDomNode=o;class a extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererTextNode=a;class i extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.attached=e.attached??[],this.attachedArray=e.attachedArray??{},this.instance=e.instance??null}attached;attachedArray;instance}e.RendererStandardNode=i}(H||(H={}));let Q;(new H.RendererRootNode).minidomType="RootNode";const Z=[],ee=[],te=e=>{Q=requestAnimationFrame((()=>te({app:e.app,renderer:$.value?.instance,scene:U.value.instance,camera:k.value.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;Z.forEach((t=>{t&&t(e)})),r&&o&&a&&r.render(t.toRaw(o),t.toRaw(a)),ee.forEach((t=>{t&&t(e)}))},ne=(e,t=1/0)=>{t===1/0?Z.push(e):Z.splice(t,0,e)},re=()=>{Q&&cancelAnimationFrame(Q)};const oe={x:"position.x",y:"position.y",z:"position.z"},ae=["","parameters"],se=["args","attach","attachArray","key","onAdded","ref","src"],ie=["geometry","material"];function ce(e,t,n,r){const o=r??e.instance,a=t.instance;e.props.attach===n&&(t.attached={[n]:o,...t.attached||{}},a[n]=r??e.instance),e.props.attachArray===n&&(t.attachedArray[e.props.attachArray]||(t.attachedArray[e.props.attachArray]=[]),t.attachedArray[e.props.attachArray].push(o),a[n]=[a[n]])}const de={createElement:(e,t,n,r)=>{const o={type:e};r&&(o.props=r);if(m(e)){const e=function(e={}){const t={domElement:document.createElement(e.type??"")};return new H.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=v(o);return ie.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new H.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new H.RendererCommentNode({...t,...e,metaType:"commentMeta"})}({text:e}),insert:(e,t,n)=>{let r=t??N();if(r.insertBefore(e,n),"commentMeta"!==e.metaType&&"textMeta"!==e.metaType&&(m(e)&&(m(t)||y(t))&&t.domElement.appendChild(e.domElement),f(e))){let n=r.metaType;if("textMeta"===n||"commentMeta"===n){const e=r.getPath();for(let t=e.length-1;t>=0;t--)if("textMeta"!==e[t].metaType&&"commentMeta"!==e[t].metaType){r=e[t];break}}if("standardMeta"===e.metaType&&"scene"!==e.type&&y(r)){const t=U.value;t.instance&&e&&t.addChild(e),e.instance&&e.instance.isObject3D&&t.instance&&t!==e&&t.instance.add(e.instance)}else f(e)&&e.instance?.isObject3D&&f(r)&&r.instance?.isObject3D&&r.instance?.add?.(e.instance);if(e?.props?.attach&&f(t)&&t?.instance){e.type?.toLowerCase().endsWith("loader")&&e.props.src&&(e.props.attach||e.props.attachArray)?function(e,t){const n=e.instance;if(t.attached=t.attached||{},t.attachedArray=t.attachedArray||{},!e.props.attach)return;if("textureloader"===e.type?.toLowerCase()){const r=n.load(e.props.src);ce(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{ce(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):ce(e,t,e.props.attach)}e.props?.onAdded&&e.props.onAdded({instance:e.instance})}},nextSibling(e){const t=e.nextSibling;return t||null},parentNode(e){const t=e.parentNode;return t||null},patchProp(e,t,n,o){m(e)?"style"===t?Object.keys(o).forEach((t=>{e.domElement.style[t]=o[t]})):e.domElement.setAttribute(t,o):y(e)||t.startsWith("$")||function({node:e,key:t,value:n}){if((e=>["onClick","onContextMenu","onDoubleClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove","onWheel"].includes(e))(t))return g({node:e,key:t,value:n});if(se.includes(t))return e;if(!f(e))return e;if("string"==typeof n&&n.startsWith("$attached")){const t=n.replace("$attached.","");n=r.get(e.attached,t,null)}const o=e.instance;if(!o)return e;const a=t.replace(/-/g,".");let s,i=oe[a]||a;for(let e=0;e<ae.length&&!s;e++){const t=[ae[e],i].filter(Boolean).join(".");s=s=r.get(o,t)}if(s&&r.isNumber(n)&&s.setScalar)s.setScalar(n);else if(s&&s.set){const e=Array.isArray(n)?n:[n];o[i].set(...e)}else"function"==typeof s?s.bind(e.instance)(...n):void 0!==r.get(o,i,void 0)?r.set(o,i,""===n||n):console.log(`No property ${i} found on ${o}`);const c=o?.texture?.type||o?.type;if("string"==typeof c){const e=c.toLowerCase();switch(!0){case e.includes("material"):o.needsUpdate=!0;break;case e.includes("camera")&&o.updateProjectionMatrix:o.updateProjectionMatrix()}}}({node:e,key:t,value:o})},remove:e=>{if(!e)return;const t=Object.keys(O),n=[];e.walk((e=>(n.push(e),!0))),n.forEach((e=>{const n=t.find((t=>O[t]?.uuid===e.uuid));if(n&&(O[n]=null),f(e)){e.instance?.removeFromParent?.();const t="scene"!==e.type&&e.instance?.dispose;t&&t.bind(e.instance)(),e.instance=null}e.drop();const r=s.findIndex((t=>t.uuid===e.uuid));-1!==r&&s.splice(r,1)}))},setElementText(){},setText(){}},ue={dpr:t.ref(1),inputActive:x,mousePos:L},le=t.computed((()=>k.value.instance)),pe=t.computed((()=>$.value?.instance??null)),he=t.computed((()=>U.value.instance));e.camera=le,e.createApp=e=>{const n=t.createRenderer(de).createApp(e);Object.keys(p).forEach((e=>{n.component(e,p[e])}));const{mount:r}=n;return n.mount=(e,...t)=>{const o=N({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});n.rootNode=o;return r(o,...t)},n.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,I(n)),u[n]=t[n]}))})({app:n,...e}),n),n},e.find=function(e){return e=t.isRef(e)?e.value:e,f(e)?e?.instance:h(e)?e?.$el?.instance:t.isVNode(e)?e.el?.instance:null},e.globals=ue,e.onAfterRender=(e,t=1/0)=>{t===1/0?ee.push(e):ee.splice(t,0,e)},e.onBeforeRender=ne,e.renderer=pe,e.scene=he,e.update=te,Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("three"),require("lodash")):"function"==typeof define&&define.amd?define(["exports","vue","three","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LunchboxRenderer={},e.vue,e.three,e.lodash)}(this,(function(e,t,n,r){"use strict";function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var a=o(n);const s=[],i=(e,n)=>{const r=K.value?.instance,o=_.value.instance,a=$.value;if(!r?.domElement||!o||!a)return;const s=(e=e??window.innerWidth)/(n=n??window.innerHeight);if("perspectivecamera"===a.type?.toLowerCase()){const e=a.instance;e.aspect=s,e.updateProjectionMatrix()}else if("orthographiccamera"===a.type?.toLowerCase()){const t=a.instance,r=n/e;t.top=10*r,t.bottom=10*-r,t.right=10,t.left=-10,t.updateProjectionMatrix()}else console.log("TODO: non-ortho or perspective camera");r.setSize(e,n),o&&a.instance&&r.render(t.toRaw(o),t.toRaw(a.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraArgs:Array,cameraLook:Array,cameraLookAt:Array,cameraPosition:Array,dpr:Number,ortho:Boolean,orthographic:Boolean,rendererProperties:Object,shadow:[Boolean,Object],transparent:Boolean},setup(e,o){const a=t.ref(),s=t.ref(!0),d=t.ref(e.dpr??-1),u=t.ref();let l,p,m;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");if(l=T(["WebGLRenderer"]),l)return s.value=!1,void(I.value=!0);{const t={antialias:!0,canvas:a.value.domElement};e.transparent&&(t.alpha=!0),K.value=g({type:"WebGLRenderer",uuid:U,props:{args:[t]}}),I.value=!0;const n=K,o={shadow:e.shadow};n.value.instance&&o?.shadow&&(n.value.instance.shadowMap.enabled=!0,"object"==typeof o.shadow&&(n.value.instance.shadowMap.type=o.shadow.type)),e.rendererProperties&&Object.keys(e.rendererProperties).forEach((t=>{r.set(n.value,t,e.rendererProperties[t])})),l=n.value}if(p=T(["PerspectiveCamera","OrthographicCamera"]),p?D.value=!0:(e.ortho||e.orthographic?$.value=g({props:{args:e.cameraArgs??[]},type:"OrthographicCamera",uuid:F}):$.value=g({props:{args:e.cameraArgs??[45,.5625,1,1e3]},type:"PerspectiveCamera",uuid:F}),D.value=!0,p=$.value),p&&e.cameraPosition&&p.instance?.position.set(...e.cameraPosition),p&&(e.cameraLookAt||e.cameraLook)){const t=e.cameraLookAt||e.cameraLook;p.instance?.lookAt(...t)}if(m=_.value,m&&m.instance&&e.background&&(m.instance.background=new n.Color(e.background)),-1===d.value&&(d.value=window.devicePixelRatio),!l?.instance)throw new Error("missing renderer");l.instance.setPixelRatio(d.value),he.dpr.value=d.value,((e,t,n)=>{const r=e.value?.domElement;if(!r)throw new Error("missing container");i();const o=new ResizeObserver((([e])=>{i()}));r&&o.observe(r),n((()=>{t&&o.unobserve(t)}))})(u,l.instance.domElement,t.onBeforeUnmount),ae({app:t.getCurrentInstance().appContext.app,camera:p.instance,renderer:l.instance,scene:m.instance})})),t.onBeforeUnmount((()=>{ie()})),()=>[o.slots.default?.()??null,t.h("div",{style:c("absolute"),ref:u},[s.value?t.h("canvas",{style:c("fixed"),class:"lunchbox-canvas",ref:a}):null])]}},u=["mesh","instancedMesh","scene","sprite","object3D","instancedBufferGeometry","bufferGeometry","boxBufferGeometry","circleBufferGeometry","coneBufferGeometry","cylinderBufferGeometry","dodecahedronBufferGeometry","extrudeBufferGeometry","icosahedronBufferGeometry","latheBufferGeometry","octahedronBufferGeometry","parametricBufferGeometry","planeBufferGeometry","polyhedronBufferGeometry","ringBufferGeometry","shapeBufferGeometry","sphereBufferGeometry","tetrahedronBufferGeometry","textBufferGeometry","torusBufferGeometry","torusKnotBufferGeometry","tubeBufferGeometry","wireframeGeometry","parametricGeometry","tetrahedronGeometry","octahedronGeometry","icosahedronGeometry","dodecahedronGeometry","polyhedronGeometry","tubeGeometry","torusKnotGeometry","torusGeometry","sphereGeometry","ringGeometry","planeGeometry","latheGeometry","shapeGeometry","extrudeGeometry","edgesGeometry","coneGeometry","cylinderGeometry","circleGeometry","boxGeometry","material","shadowMaterial","spriteMaterial","rawShaderMaterial","shaderMaterial","pointsMaterial","meshPhysicalMaterial","meshStandardMaterial","meshPhongMaterial","meshToonMaterial","meshNormalMaterial","meshLambertMaterial","meshDepthMaterial","meshDistanceMaterial","meshBasicMaterial","meshMatcapMaterial","lineDashedMaterial","lineBasicMaterial","light","spotLightShadow","spotLight","pointLight","rectAreaLight","hemisphereLight","directionalLightShadow","directionalLight","ambientLight","lightShadow","ambientLightProbe","hemisphereLightProbe","lightProbe","texture","videoTexture","dataTexture","dataTexture3D","compressedTexture","cubeTexture","canvasTexture","depthTexture","textureLoader","group","catmullRomCurve3","points","cameraHelper","camera","perspectiveCamera","orthographicCamera","cubeCamera","arrayCamera","webGLRenderer"],l={},p=["canvas","div","LunchboxWrapper"];u.map((e=>t.defineComponent({inheritAttrs:!1,name:e,setup:(n,r)=>()=>t.h(e,r.attrs,r.slots?.default?.()||[])}))).reduce(((e,t)=>(e[t.name]=t,e)));const m={...u,Lunchbox:d};const h=e=>e?.$el&&e?.$el?.hasOwnProperty?.("instance"),f=e=>{if("domMeta"===e?.metaType)return!0;const t="string"==typeof e?e:e?.type;return p.includes(t??"")},y=e=>"standardMeta"===e?.metaType,v=e=>e.isLunchboxRootNode;function g(e={},t={}){const n={attached:e.attached??[],attachedArray:e.attachedArray??{},instance:e.instance??null},r=new Q.RendererStandardNode({...e,...n,metaType:"standardMeta"});return!r.type||v(r)||r.instance||(r.instance=function(e){if(!e.type)return null;const t=e.type[0].toUpperCase()+e.type.slice(1),n=l[e.type]||a[t];if(!n)throw`${t} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`;const r=(e.props.args??[]).map((t=>function({node:e,prop:t}){const n="string"==typeof t&&t.startsWith("$attachedArray"),r=function({node:e,prop:t}){if("string"==typeof t&&t.startsWith("$attachedArray"))return e.attachedArray[t.replace("$attachedArray.","")];if("string"==typeof t&&t.startsWith("$attached"))return e.attached[t.replace("$attached.","")];return t}({node:e,prop:t});return Array.isArray(r)&&n?r:[r]}({node:e,prop:t})));let o=[];r.forEach((e=>{o=o.concat(e)}));return new n(...o)}({...r,props:{...r.props,...t}})),"scene"===r.type&&(_.value=r),r}const b=[],x=t.ref(!1);function R({node:e,key:n,value:r}){var o;if(e.eventListeners[n]||(e.eventListeners[n]=[]),e.eventListenerRemoveFunctions[n]||(e.eventListenerRemoveFunctions[n]=[]),e.eventListeners[n].push(r),A.includes(n)&&(V.value,e.instance&&!b.includes(e)&&(o=e,b.push(o),e.eventListenerRemoveFunctions[n].push((()=>(e=>{const t=b.indexOf(e);-1!==t&&b.splice(t,1)})(e))))),"onClick"===n||"onPointerDown"===n||"onPointerUp"===n){const r=t.watch((()=>x.value),(t=>{console.log(t,M);const r=M.map((e=>e.element)).findIndex((t=>t.instance&&t.instance.uuid===e.instance?.uuid));-1!==r&&((!t||"onClick"!==n&&"onPointerDown"!==n)&&(t||"onPointerUp"!==n)||e.eventListeners[n].forEach((e=>{e({intersection:M[r].intersection})})))}));e.eventListenerRemoveFunctions[n].push(r)}return e}const A=["onClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove"];let w,C,E;const L=t.ref({x:1/0,y:1/0});let P=!1;let M=[];const B=()=>{const e=V.value?.instance,t=$.value?.instance;if(!e||!t)return;e.setFromCamera(he.mousePos.value,t);const n=e.intersectObjects(b.map((e=>e.instance)));let r=[],o=[],a=[];r=M.map((e=>e.intersection)),n?.forEach((e=>{const t=M.findIndex((t=>t.intersection.object===e.object));if(-1===t){const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&o.push({element:t,intersection:e})}else{const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&a.push({element:t,intersection:e})}const n=r.findIndex((t=>t.object.uuid===e.object.uuid));-1!==n&&r.splice(n,1)}));const s=r.map((e=>({element:b.find((t=>t.instance?.uuid===e.object.uuid)),intersection:e})));o.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerEnter"],intersection:t})})),a.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerOver","onPointerMove"],intersection:t})})),s.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerLeave","onPointerOut"],intersection:t})})),M=[].concat(o,a)},G=({element:e,eventKeys:t,intersection:n})=>{e&&t.forEach((t=>{e.eventListeners[t]&&e.eventListeners[t].forEach((e=>{e({intersection:n})}))}))};function N(t={}){return e.lunchboxTree||(e.lunchboxTree=new Q.RendererRootNode(t)),e.lunchboxTree}function T(e){Array.isArray(e)||(e=[e]);for(let t of e)if(j[t])return j[t];for(let t of e){const e=O[t]||s.find((e=>e.type?.toLowerCase()===t.toLowerCase()));if(e){const n=e;return O[t]=n,n}}return null}e.lunchboxTree=void 0;const O=t.reactive({}),j=t.reactive({});function k(e,n,r={},o=null){Array.isArray(e)||(e=[e]);for(let t of e)O[t]||(O[t]=null),j[t]||(j[t]=null);return t.computed({get(){const t=T(e);if(t)return t;const a=N(),s=g({type:e[0],uuid:n,props:r});return a.addChild(s),O[e[0]]=s,o&&o(s),s},set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}})}const F="FALLBACK_CAMERA",S=k(["PerspectiveCamera","OrthographicCamera"],F,{args:[45,.5625,1,1e3]}),D=t.ref(!1),$=t.computed({get:()=>D.value?S.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}}),U="FALLBACK_RENDERER",W=k(["WebGLRenderer"],U,{}),I=t.ref(!1),K=t.computed({get:()=>I.value?W.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}}),_=k("Scene","FALLBACK_SCENE"),V=k("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>K.value),(e=>{e?.instance&&(P||(w=t=>{const n=(e.instance.domElement.width??1)/he.dpr.value,r=(e.instance.domElement.height??1)/he.dpr.value;L.value.x=t.offsetX/n*2-1,L.value.y=-t.offsetY/r*2+1},C=()=>x.value=!0,E=()=>x.value=!1,e.instance.domElement.addEventListener("mousemove",w),e.instance.domElement.addEventListener("mousedown",C),e.instance.domElement.addEventListener("mouseup",E),se(B),P=!0),n&&n())}),{immediate:!0})})(e))),q=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var z,H=new Uint8Array(16);function Y(){if(!z&&!(z="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return z(H)}var X=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function J(e){return"string"==typeof e&&X.test(e)}for(var Q,Z=[],ee=0;ee<256;++ee)Z.push((ee+256).toString(16).substr(1));function te(e,t,n){var r=(e=e||{}).random||(e.rng||Y)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(var o=0;o<16;++o)t[n+o]=r[o];return t}return function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(Z[e[t+0]]+Z[e[t+1]]+Z[e[t+2]]+Z[e[t+3]]+"-"+Z[e[t+4]]+Z[e[t+5]]+"-"+Z[e[t+6]]+Z[e[t+7]]+"-"+Z[e[t+8]]+Z[e[t+9]]+"-"+Z[e[t+10]]+Z[e[t+11]]+Z[e[t+12]]+Z[e[t+13]]+Z[e[t+14]]+Z[e[t+15]]).toLowerCase();if(!J(n))throw TypeError("Stringified UUID is invalid");return n}(r)}!function(e){e.BaseNode=class{constructor(e={},t){this.parentNode=e?.parentNode??t??null,this.minidomType="MinidomBaseNode",this.uuid=e?.uuid??te(),s.push(this)}uuid;parentNode;get nextSibling(){if(!this.parentNode)return null;const e=this.parentNode.children.findIndex((e=>e.uuid===this.uuid));return-1!==e&&e<this.parentNode.children.length-1?this.parentNode.children[e+1]:null}insertBefore(e,t){e.removeAsChildFromAnyParents(),e.parentNode=this;const n=this.children.findIndex((e=>e.uuid===t?.uuid));-1!==n?this.children.splice(n,0,e):this.children.push(e)}removeChild(e){const t=this.children.findIndex((t=>t?.uuid===e?.uuid));-1!==t&&this.children.splice(t,1)}children=[];addChild(e){return e&&(e.removeAsChildFromAnyParents(),e.parentNode=this,this.insertBefore(e,null)),this}getPath(){const e=[];let t=this;for(;t;)e.unshift(t),t=t.parentNode;return e}drop(){this.parentNode=null,this.removeAsChildFromAnyParents()}walk(e){const t=[this,...this.children],n=[];let r=!0;for(;t.length&&r;){const o=t.shift();if(o){if(n.includes(o))continue;n.push(o),t.push(...o.children.filter((e=>!n.includes(e)))),r=e(o)}else r=!1}}minidomType;removeAsChildFromAnyParents(){s.forEach((e=>e.removeChild(this)))}};class t extends e.BaseNode{constructor(e={},t){super(e,t),this.minidomType="RendererNode",this.eventListeners={},this.eventListenerRemoveFunctions={},this.name=e.name??"",this.metaType=e.metaType??"standardMeta",this.props=e.props??[],this.type=e.type??""}eventListeners;eventListenerRemoveFunctions;name;metaType;props;type;drop(){super.drop(),Object.keys(this.eventListenerRemoveFunctions).forEach((e=>{this.eventListenerRemoveFunctions[e].forEach((e=>e()))}))}}e.RendererBaseNode=t;class n extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement;isLunchboxRootNode=!0}e.RendererRootNode=n;class r extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererCommentNode=r;class o extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement}e.RendererDomNode=o;class a extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererTextNode=a;class i extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.attached=e.attached??[],this.attachedArray=e.attachedArray??{},this.instance=e.instance??null}attached;attachedArray;instance}e.RendererStandardNode=i}(Q||(Q={}));let ne;(new Q.RendererRootNode).minidomType="RootNode";const re=[],oe=[],ae=e=>{ne=requestAnimationFrame((()=>ae({app:e.app,renderer:K.value?.instance,scene:_.value.instance,camera:$.value?.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;re.forEach((t=>{t&&t(e)})),r&&o&&a&&(n.customRender?n.customRender(e):r.render(t.toRaw(o),t.toRaw(a))),oe.forEach((t=>{t&&t(e)}))},se=(e,t=1/0)=>{t===1/0?re.push(e):re.splice(t,0,e)},ie=()=>{ne&&cancelAnimationFrame(ne)};const ce={x:"position.x",y:"position.y",z:"position.z"},de=["","parameters"],ue=["args","attach","attachArray","key","onAdded","ref","src"],le=["geometry","material"];function pe(e,t,n,r){const o=r??e.instance,a=t.instance;e.props.attach===n&&(t.attached={[n]:o,...t.attached||{}},a[n]=r??e.instance),e.props.attachArray===n&&(t.attachedArray[e.props.attachArray]||(t.attachedArray[e.props.attachArray]=[]),t.attachedArray[e.props.attachArray].push(o),a[n]=[a[n]])}const me={createElement:(e,t,n,r)=>{const o={type:e};r&&(o.props=r);if(f(e)){const e=function(e={}){const t={domElement:document.createElement(e.type??"")};return new Q.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=g(o);return le.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new Q.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new Q.RendererCommentNode({...t,...e,metaType:"commentMeta"})}({text:e}),insert:(e,t,n)=>{let r=t??N();if(r.insertBefore(e,n),"commentMeta"!==e.metaType&&"textMeta"!==e.metaType&&(f(e)&&(f(t)||v(t))&&t.domElement.appendChild(e.domElement),y(e))){let n=r.metaType;if("textMeta"===n||"commentMeta"===n){const e=r.getPath();for(let t=e.length-1;t>=0;t--)if("textMeta"!==e[t].metaType&&"commentMeta"!==e[t].metaType){r=e[t];break}}if("standardMeta"===e.metaType&&"scene"!==e.type&&v(r)){const t=_.value;t.instance&&e&&t.addChild(e),e.instance&&e.instance.isObject3D&&t.instance&&t!==e&&t.instance.add(e.instance)}else y(e)&&e.instance?.isObject3D&&y(r)&&r.instance?.isObject3D&&r.instance?.add?.(e.instance);if(e?.props?.attach&&y(t)&&t?.instance){e.type?.toLowerCase().endsWith("loader")&&e.props.src&&(e.props.attach||e.props.attachArray)?function(e,t){const n=e.instance;if(t.attached=t.attached||{},t.attachedArray=t.attachedArray||{},!e.props.attach)return;if("textureloader"===e.type?.toLowerCase()){const r=n.load(e.props.src);pe(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{pe(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):pe(e,t,e.props.attach)}e.props?.onAdded&&e.props.onAdded({instance:e.instance})}},nextSibling(e){const t=e.nextSibling;return t||null},parentNode(e){const t=e.parentNode;return t||null},patchProp(e,t,n,o){f(e)?"style"===t?Object.keys(o).forEach((t=>{e.domElement.style[t]=o[t]})):e.domElement.setAttribute(t,o):v(e)||t.startsWith("$")||function({node:e,key:t,value:n}){if((e=>["onClick","onContextMenu","onDoubleClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove","onWheel"].includes(e))(t))return R({node:e,key:t,value:n});if(ue.includes(t))return e;if(!y(e))return e;if("string"==typeof n&&n.startsWith("$attached")){const t=n.replace("$attached.","");n=r.get(e.attached,t,null)}const o=e.instance;if(!o)return e;const a=t.replace(/-/g,".");let s,i=ce[a]||a;for(let e=0;e<de.length&&!s;e++){const t=[de[e],i].filter(Boolean).join(".");s=s=r.get(o,t)}if(s&&r.isNumber(n)&&s.setScalar)s.setScalar(n);else if(s&&s.set){const e=Array.isArray(n)?n:[n];o[i].set(...e)}else"function"==typeof s?s.bind(e.instance)(...n):void 0!==r.get(o,i,void 0)?r.set(o,i,""===n||n):console.log(`No property ${i} found on ${o}`);const c=o?.texture?.type||o?.type;if("string"==typeof c){const e=c.toLowerCase();switch(!0){case e.includes("material"):o.needsUpdate=!0;break;case e.includes("camera")&&o.updateProjectionMatrix:o.updateProjectionMatrix()}}}({node:e,key:t,value:o})},remove:e=>{if(!e)return;const t=Object.keys(j),n=[];e.walk((e=>(n.push(e),!0))),n.forEach((e=>{const n=t.find((t=>j[t]?.uuid===e.uuid));if(n&&(j[n]=null),y(e)){e.instance?.removeFromParent?.();const t="scene"!==e.type&&e.instance?.dispose;t&&t.bind(e.instance)(),e.instance=null}e.drop();const r=s.findIndex((t=>t.uuid===e.uuid));-1!==r&&s.splice(r,1)}))},setElementText(){},setText(){}},he={dpr:t.ref(1),inputActive:x,mousePos:L},fe=t.computed((()=>$.value?.instance??null)),ye=t.computed((()=>K.value?.instance??null)),ve=t.computed((()=>_.value.instance));let ge=null,be=null;e.camera=fe,e.clearCustomRender=()=>{ge?ge.clearCustomRender():be=null},e.createApp=e=>{ge=t.createRenderer(me).createApp(e),Object.keys(m).forEach((e=>{ge.component(e,m[e])}));const{mount:n}=ge;return ge.mount=(e,...t)=>{const r=N({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});ge.rootNode=r;return n(r,...t)},ge.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,q(n)),l[n]=t[n]}))})({app:ge,...e}),ge),ge.setCustomRender=e=>{ge.customRender=e},be&&(ge.setCustomRender(be),be=null),ge.clearCustomRender=()=>{ge.customRender=null},ge},e.find=function(e){return e=t.isRef(e)?e.value:e,y(e)?e?.instance:h(e)?e?.$el?.instance:t.isVNode(e)?e.el?.instance:null},e.globals=he,e.offAfterRender=e=>{if(isFinite(e))oe.splice(e,1);else{const t=oe.findIndex((t=>t==e));oe.splice(t,1)}},e.offBeforeRender=e=>{if(isFinite(e))re.splice(e,1);else{const t=re.findIndex((t=>t==e));re.splice(t,1)}},e.onAfterRender=(e,t=1/0)=>{t===1/0?oe.push(e):oe.splice(t,0,e)},e.onBeforeRender=se,e.renderer=ye,e.scene=ve,e.setCustomRender=e=>{ge?ge.setCustomRender(e):be=e},Object.defineProperty(e,"__esModule",{value:!0})}));