Commit Needle production dist and nginx-only Docker image

- Track Needle/MenuScene/dist and Needle/SampleScene/dist for container deploys
- Dockerfile copies pre-built dist (no npm in image); rebuild with npm run build before commit
- Fix Needle .gitignore: /assets/ so dist/assets is not ignored
- Git LFS: track *.wasm; relax .dockerignore so dist is sent as build context

Made-with: Cursor
This commit is contained in:
pelpanagiotis
2026-04-19 23:39:59 +03:00
parent 98062ef858
commit 6947303755
169 changed files with 91778 additions and 31 deletions
@@ -0,0 +1 @@
import{t as e}from"./needle-engine@5.0.3.js";export{e as GenerateMeshBVHWorker};
Binary file not shown.
@@ -0,0 +1 @@
import{u as e}from"./materialx.CnHmG--Y.js";export{e as default};
@@ -0,0 +1 @@
import{c as e}from"./materialx.CnHmG--Y.js";export{e as default};
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
import{l as e}from"./materialx.CnHmG--Y.js";export{e as default};
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
import{n as e,r as t,t as n}from"./postprocessing.ao.BRYreHJS.js";export{e as DepthType,n as N8AOPass,t as N8AOPostPass};
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./register_types.C910Zu9b.js","./needle-engine-webxr.DQA26K-l.js","./materialx.CnHmG--Y.js","./rolldown-runtime.CYVBeYYp.js","./three@0.169.19.js","./needle-engine-ui.BzyLX9fs.js","./gltf-progressive.BBJGcb3s.js","./three-examples@0.169.19.js","./three-mesh-ui.CgGzZ3ml.js","./needle-engine@5.0.3.js","./needle-engine.extras.t1Dx-yNB.js","./needle-engine-particles.Bw3zzNt3.js","./three-quarks.DALdLWPD.js","./needle-engine.extras.CDv9-f43.js","./postprocessing.Wy71DpiM.js","./three-mesh-bvh.B-oXEGo2.js","./needle-engine.V_YEpsUE.js"])))=>i.map(i=>d[i]);
import{d as e}from"./materialx.CnHmG--Y.js";import{_t as t,fn as n,wi as r}from"./needle-engine-ui.BzyLX9fs.js";import"./needle-engine@5.0.3.js";import{x as i}from"./needle-engine-webxr.DQA26K-l.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})(),globalThis[`needle:dependencies:ready`]=e(()=>import(`./register_types.C910Zu9b.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]),import.meta.url);var a=[];globalThis[`needle:codegen_files`]=a,a.push(`./assets/MenuScene.glb`),document.addEventListener(`DOMContentLoaded`,()=>{let e=document.querySelector(`needle-engine`);e&&e.getAttribute(`src`)===null&&(e.setAttribute(`hash`,`1776630853539`),e.setAttribute(`src`,JSON.stringify(a)))}),console.log(`Made with ♥ by 🌵 Needle - https://needle.tools — Version 5.0.3`),r(e=>{let t=e.scene.getComponentInChildren(i);t||(t=e.scene.addComponent(i),t.createARButton=!0,t.createVRButton=!0),t.autoPlace=!0,t.autoCenter=!0,t.arScale=1});function o(e){document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>e(),{once:!0}):e()}function s(){let e=document.querySelector(`needle-engine`),r=document.querySelector(`#asset-picker-prev`),i=document.querySelector(`#asset-picker-next`),a=document.querySelector(`#asset-picker-ar`),s=document.querySelector(`#asset-picker-label`),c=document.querySelector(`#asset-picker-index`);if(!e||!r||!i||!a||!s||!c)return;let l=null,u=!1,d=!1,f=!1,p=()=>{l&&l.getDishSlotCount()>0?(s.textContent=l.getPickerLabel(),c.textContent=``):l?(s.textContent=`Menu (assign dishes in Unity)`,c.textContent=``):(s.textContent=`Menu scene`,c.textContent=`—`);let e=l!==null&&l.getDishSlotCount()>1;r.disabled=!e,i.disabled=!e,a.disabled=!d||f||u},m=async()=>{try{let n=await e.getContext();l=t(MenuController,n)}catch{l=null}p()};n.isARSupported().then(e=>{d=e,p()});let h=e=>{!l||l.getDishSlotCount()<=1||(e<0?l.selectPreviousDish():l.selectNextDish(),p())},g=async()=>{if(!(!d||f||u)){f=!0,p();try{let t=await e.getContext();await n.start(`immersive-ar`,void 0,t)}catch(e){console.warn(`[assetPicker] Failed to start AR session:`,e)}finally{f=!1,p()}}};r.addEventListener(`click`,()=>h(-1)),i.addEventListener(`click`,()=>h(1)),a.addEventListener(`click`,()=>void g()),e.addEventListener(`enter-ar`,()=>{u=!0,p()}),e.addEventListener(`exit-ar`,()=>{u=!1,p()}),e.addEventListener(`enter-vr`,()=>{u=!0,p()}),e.addEventListener(`exit-vr`,()=>{u=!1,p()}),e.addEventListener(`loadfinished`,()=>void m()),o(()=>{requestAnimationFrame(()=>void m())})}s(),e(()=>import(`./needle-engine.V_YEpsUE.js`),__vite__mapDeps([16,10,2,3,4,1,5,6,7,8,11,12,13,14,9,15]),import.meta.url);
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
html{height:-webkit-fill-available}body{margin:0;padding:0}needle-engine{width:100%;height:100%;position:absolute;top:0;left:0}#asset-picker{left:0;right:0;bottom:calc(4.75rem + env(safe-area-inset-bottom,0px));z-index:600;pointer-events:auto;box-sizing:border-box;justify-content:center;padding:12px;display:flex;position:fixed}#asset-picker .asset-picker__inner{color:#f2f2f7;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:#0f0f14d1;border-radius:12px;flex-wrap:wrap;align-items:center;gap:12px;max-width:min(100%,36rem);padding:10px 14px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;display:flex;box-shadow:0 4px 24px #00000059}#asset-picker button{pointer-events:auto;touch-action:manipulation;cursor:pointer;font:inherit;color:#0f0f14;background:#e8e8ed;border:none;border-radius:8px;padding:8px 14px;font-weight:600}#asset-picker button:disabled{opacity:.45;cursor:not-allowed}#asset-picker #asset-picker-ar{color:#0a0a0c;background:#34c759}#asset-picker #asset-picker-ar:disabled{color:#ffffff80;background:#3a3a3e}#asset-picker .asset-picker__label{text-overflow:ellipsis;white-space:nowrap;text-align:center;flex:1;min-width:0;overflow:hidden}#asset-picker .asset-picker__index{opacity:.85;font-variant-numeric:tabular-nums;flex-shrink:0;font-size:.85rem}
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./materialx.CnHmG--Y.js";export{o as Experimental_API,e as MaterialXEnvironment,n as MaterialXLoader,t as MaterialXMaterial,r as preloadWasm,a as ready,i as useNeedleMaterialX};
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1 @@
import{u as e}from"./needle-engine@5.0.3.js";export{e as NeedleEngineWebComponent};
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1 @@
import{a as e,i as t,n,r}from"./three-mesh-bvh.B-oXEGo2.js";export{e as MeshBVH,n as StaticGeometryGenerator,r as acceleratedRaycast,t as computeBoundsTree};
Binary file not shown.
@@ -0,0 +1 @@
import{t as e}from"./needle-engine.D6xdy26G.js";export{e as GLTFAnimationPointerExtension};
@@ -0,0 +1 @@
import{$ as ee,$t as te,A as ne,At as e,B as t,Bt as n,C as r,Ct as re,D as ie,Dt as ae,E as oe,Et as i,F as a,Ft as o,G as s,Gt as c,H as l,Ht as u,I as d,It as f,J as p,Jt as m,K as h,Kt as g,L as _,Lt as v,M as y,Mt as b,N as x,Nt as S,O as C,Ot as w,P as T,Pt as E,Q as D,Qt as O,R as k,Rt as A,S as j,St as M,T as N,Tt as P,U as F,Ut as I,V as L,Vt as R,W as z,Wt as B,X as V,Xt as H,Y as U,Yt as W,Z as G,Zt as K,_ as q,_t as se,a as ce,an as le,at as J,b as ue,bt as Y,c as de,cn as fe,ct as pe,d as me,dt as he,en as ge,et as _e,f as ve,ft as ye,g as be,gt as xe,h as Se,ht as X,i as Ce,in as we,it as Te,j as Ee,jt as De,k as Oe,kt as ke,l as Ae,ln as je,lt as Z,m as Me,mt as Ne,n as Pe,nn as Fe,nt as Ie,o as Le,on as Re,ot as Q,p as ze,pt as Be,q as Ve,qt as He,r as Ue,rn as We,rt as Ge,s as Ke,sn as qe,st as Je,t as Ye,tn as Xe,tt as Ze,u as Qe,ut as $e,v as et,vt as tt,w as nt,wt as rt,x as $,xt as it,y as at,yt as ot,z as st,zt as ct}from"./postprocessing.Wy71DpiM.js";export{Ye as ASCIIEffect,Pe as ASCIITexture,Ue as AdaptiveLuminanceMaterial,Ce as AdaptiveLuminancePass,ce as BlendFunction,Le as BlendMode,Ke as BloomEffect,Q as BlurPass,Q as KawaseBlurPass,de as BokehEffect,Ae as BokehMaterial,Qe as BoxBlurMaterial,me as BoxBlurPass,ve as BrightnessContrastEffect,ze as ChromaticAberrationEffect,Me as CircleOfConfusionMaterial,Se as ClearMaskPass,be as ClearPass,q as ColorAverageEffect,et as ColorChannel,at as ColorDepthEffect,_ as ColorEdgesMaterial,_ as EdgeDetectionMaterial,J as ConvolutionMaterial,J as KawaseBlurMaterial,ue as CopyMaterial,$ as CopyPass,$ as SavePass,j as DepthComparisonMaterial,r as DepthCopyMaterial,nt as DepthCopyMode,N as DepthCopyPass,N as DepthSavePass,oe as DepthDownsamplingMaterial,ie as DepthDownsamplingPass,C as DepthEffect,Oe as DepthMaskMaterial,ne as DepthOfFieldEffect,Ee as DepthPass,y as DepthPickingPass,x as DepthTestStrategy,T as Disposable,a as DotScreenEffect,d as DownsamplingMaterial,k as EdgeDetectionMode,st as Effect,t as EffectAttribute,L as EffectComposer,l as EffectMaterial,F as EffectPass,z as EffectShaderData,s as EffectShaderSection,s as Section,h as FXAAEffect,Ve as GammaCorrectionEffect,p as GaussKernel,U as GaussianBlurMaterial,V as GaussianBlurPass,G as GlitchEffect,D as GlitchMode,ee as GodRaysEffect,_e as GodRaysMaterial,Ze as GridEffect,Ie as HueSaturationEffect,Ge as ImmutableTimer,Te as Initializable,Je as KernelSize,pe as LUT1DEffect,Z as LUT3DEffect,Z as LUTEffect,$e as LUT3dlLoader,he as LUTCubeLoader,ye as LUTOperation,Be as LambdaPass,Ne as LensDistortionEffect,X as LookupTexture,X as LookupTexture3D,xe as LuminanceMaterial,se as LuminancePass,tt as MaskFunction,ot as MaskMaterial,Y as MaskPass,it as MipmapBlurPass,M as NoiseEffect,re as NoiseTexture,rt as NormalPass,i as OutlineEdgesMaterial,i as OutlineMaterial,P as OutlineEffect,ae as OverrideMaterialManager,w as Pass,ke as PixelationEffect,e as PredicationMode,De as RawImageData,b as RealisticBokehEffect,S as RenderPass,E as Resizable,o as Resizer,o as Resolution,f as SMAAAreaImageData,v as SMAAEffect,A as SMAAImageGenerator,ct as SMAAImageLoader,n as SMAAPreset,R as SMAASearchImageData,u as SMAAWeightsMaterial,I as SSAOEffect,B as SSAOMaterial,c as ScanlineEffect,g as Selection,He as SelectiveBloomEffect,m as SepiaEffect,W as ShaderPass,H as ShockWaveEffect,K as TetrahedralUpscaler,O as TextureEffect,te as TiltShiftBlurMaterial,ge as TiltShiftBlurPass,Xe as TiltShiftEffect,Fe as Timer,We as ToneMappingEffect,we as ToneMappingMode,le as UpsamplingMaterial,Re as VignetteEffect,qe as VignetteTechnique,fe as WebGLExtension,je as version};
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
+41
View File
@@ -0,0 +1,41 @@
import{Ar as e,Kn as t,_n as n,fn as r,kr as i}from"./three@0.169.19.js";import{$i as a,Xi as o,ct as s,eo as c,ot as l}from"./needle-engine-ui.BzyLX9fs.js";import"./needle-engine@5.0.3.js";import{m as u}from"./needle-engine-webxr.DQA26K-l.js";import{m as d,t as f}from"./needle-engine.extras.CDv9-f43.js";var p=class extends l{raycaster=new t;touchPos=new i;plane=new n(new e(0,1,0),0);initialPinchDistance=0;initialScale=new e;isScaling=!1;onEnable(){let e=this.context.renderer.domElement;e.addEventListener(`touchstart`,this.onTouchStart),e.addEventListener(`touchmove`,this.onTouchMove),e.addEventListener(`touchend`,this.onTouchEnd)}onDisable(){let e=this.context.renderer.domElement;e.removeEventListener(`touchstart`,this.onTouchStart),e.removeEventListener(`touchmove`,this.onTouchMove),e.removeEventListener(`touchend`,this.onTouchEnd)}onTouchStart=e=>{if(e.touches.length===2){this.isScaling=!0;let t=e.touches[0],n=e.touches[1];this.initialPinchDistance=Math.hypot(n.clientX-t.clientX,n.clientY-t.clientY),this.initialScale.copy(this.gameObject.scale)}};onTouchMove=t=>{if(t.preventDefault(),this.isScaling&&t.touches.length===2){let e=t.touches[0],n=t.touches[1],r=Math.hypot(n.clientX-e.clientX,n.clientY-e.clientY)/this.initialPinchDistance,i=this.initialScale.clone().multiplyScalar(r);this.gameObject.scale.copy(i)}else if(t.touches.length===1&&!this.isScaling){let n=t.touches[0],r=this.context.renderer.domElement.getBoundingClientRect();this.touchPos.set((n.clientX-r.left)/r.width*2-1,-((n.clientY-r.top)/r.height)*2+1),this.raycaster.setFromCamera(this.touchPos,this.context.mainCamera);let i=new e;this.raycaster.ray.intersectPlane(this.plane,i)&&this.gameObject.position.copy(i)}};onTouchEnd=e=>{e.touches.length<2&&(this.isScaling=!1)}};function m(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var h=new WeakMap,g=class extends l{isMobile=!1;isDesktop=!1;isXR=!1;dishName=``;dishes=[];webXROrigin;dishBobAmplitude=.05;dishBobSpeed=2.5;usdzExporter;arSessionBobPaused=!1;selectedDishIndex=0;onEnable(){if(this.dishName=new URLSearchParams(window.location.search).get(`dishName`)??``,this.webXROrigin&&(this.usdzExporter=this.webXROrigin.getComponent(u)??void 0),this.dishName){let e=!1;this.dishes.forEach((t,n)=>{t&&t.name===this.dishName&&(this.selectedDishIndex=n,e=!0)}),this.dishes.forEach(t=>{if(!t)return;let n=e&&t.name===this.dishName;n||this.restoreDishBaseY(t),s.setActive(t,n)}),e||this.ensureOnlySelectedDishVisible()}else this.ensureOnlySelectedDishVisible();this.updateUSDZExporterTarget(),this.checkForDeviceType().then(()=>{this.isMobile?console.log(`[MenuController] isMobile`):this.isDesktop?this.setupDesktopControls():this.isXR}),this.setupMobileControls(),this.disableDoubleTapZoom()}onEnterXR(e){e.xr.mode===`immersive-ar`&&(this.arSessionBobPaused=!0,this.snapActiveDishToBaseY())}onLeaveXR(e){this.arSessionBobPaused=!1}update(){if(this.arSessionBobPaused||this.dishBobAmplitude<=0||this.getValidDishIndices().length===0)return;let e=this.dishes[this.selectedDishIndex];if(!e)return;let t=h.get(e);t===void 0&&(t=e.position.y,h.set(e,t));let n=this.context.time.time;e.position.y=t+Math.sin(n*this.dishBobSpeed)*this.dishBobAmplitude}async checkForDeviceType(){await this.isXRDevice()?this.isXR=!0:(console.log(`DeviceUtilities.isMobileDevice()`,c.isMobileDevice()),this.isMobile=c.isMobileDevice(),this.isMobile||(this.isDesktop=c.isDesktop()))}async isXRDevice(){if(navigator.xr)try{return await navigator.xr.isSessionSupported(`immersive-vr`)}catch{return console.log(`XR check error!`),!1}return!1}setupMobileControls(){typeof document<`u`&&document.querySelector(`#asset-picker`)||this.createMenuMobileControls()}setupDesktopControls(){}createMenuMobileControls(){let e=document.createElement(`div`);e.id=`menuControlsZone`,e.style.cssText=`
position: absolute;
display: flex;
justify-content: space-between;
bottom: 10%;
left: 10%;
right: 10%;
height: 150px;
`,document.body.appendChild(e);let t=document.createElement(`button`);t.id=`previousButton`,t.style.cssText=`
height: 100px;
width: 100px;
background-color: #ffffff;
color: #111111;
border: none;
border-radius: 50px;
box-shadow: 0 8px 24px rgba(0,0,0,0.25);
display: flex;
align-items: center;
justify-content: center;
touch-action: manipulation;
`,t.setAttribute(`aria-label`,`Previous`),t.innerHTML=`
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 18L9 12L15 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
`,t.onclick=this.selectPreviousDish.bind(this);let n=document.createElement(`button`);n.id=`nextButton`,n.style.cssText=`
height: 100px;
width: 100px;
background-color: #ffffff;
color: #111111;
border: none;
border-radius: 50px;
box-shadow: 0 8px 24px rgba(0,0,0,0.25);
display: flex;
align-items: center;
justify-content: center;
touch-action: manipulation;
`,n.setAttribute(`aria-label`,`Next`),n.innerHTML=`
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 6L15 12L9 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
`,n.onclick=this.selectNextDish.bind(this),this.dishName&&(t.disabled=!0,t.style.display=`none`,n.disabled=!0,n.style.display=`none`),e.appendChild(t),e.appendChild(n)}disableDoubleTapZoom(){let e=0;document.addEventListener(`touchend`,t=>{let n=Date.now();n-e<=300&&t.preventDefault(),e=n},{passive:!1})}getValidDishIndices(){return this.dishes.map((e,t)=>e==null?-1:t).filter(e=>e>=0)}ensureOnlySelectedDishVisible(){let e=this.getValidDishIndices();if(e.length===0)return;let t=this.selectedDishIndex;e.indexOf(t)<0&&(t=e[0],this.selectedDishIndex=t),e.forEach(e=>{let t=e===this.selectedDishIndex,n=this.dishes[e];t||this.restoreDishBaseY(n),s.setActive(this.dishes[e],t)})}restoreDishBaseY(e){if(!e)return;let t=h.get(e);t!==void 0&&(e.position.y=t)}snapActiveDishToBaseY(){this.restoreDishBaseY(this.dishes[this.selectedDishIndex])}getDishSlotCount(){return this.getValidDishIndices().length}getPickerLabel(){let e=this.getValidDishIndices();if(e.length===0)return`Menu`;let t=Math.max(0,e.indexOf(this.selectedDishIndex)),n=this.dishes[this.selectedDishIndex]?.name?.trim();return n?`${n} (${t+1}/${e.length})`:`Dish ${t+1} / ${e.length}`}selectPreviousDish(){let e=this.getValidDishIndices();if(e.length===0)return;let t=e.indexOf(this.selectedDishIndex);t<0&&(t=0),this.restoreDishBaseY(this.dishes[e[t]]),s.setActive(this.dishes[e[t]],!1),t=(t-1+e.length)%e.length,this.selectedDishIndex=e[t],s.setActive(this.dishes[this.selectedDishIndex],!0),this.updateUSDZExporterTarget()}selectNextDish(){let e=this.getValidDishIndices();if(e.length===0)return;let t=e.indexOf(this.selectedDishIndex);t<0&&(t=0),this.restoreDishBaseY(this.dishes[e[t]]),s.setActive(this.dishes[e[t]],!1),t=(t+1)%e.length,this.selectedDishIndex=e[t],s.setActive(this.dishes[this.selectedDishIndex],!0),this.updateUSDZExporterTarget()}updateUSDZExporterTarget(){let e=this.dishes[this.selectedDishIndex];this.usdzExporter&&e&&(this.usdzExporter.objectToExport=e)}getUrlParameter(e){return new URLSearchParams(window.location.search).get(e)}};m([o(r)],g.prototype,`dishes`,void 0),m([o(r)],g.prototype,`webXROrigin`,void 0),m([o()],g.prototype,`dishBobAmplitude`,void 0),m([o()],g.prototype,`dishBobSpeed`,void 0);var _=class extends l{volume;start(){if(!this.volume){console.warn(`No PostProcessVolume assigned`);return}this.volume.addEffect(new d({intensity:3,luminanceThreshold:.2}))}};m([o(f)],_.prototype,`volume`,void 0);function v(){a.add(`ARObjectController`,p),a.add(`MenuController`,g),a.add(`PostProcessingVolumeController`,_)}v();export{v as registerTypes};
Binary file not shown.
@@ -0,0 +1 @@
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));export{s as n,l as r,o as t};
Binary file not shown.
@@ -0,0 +1 @@
import{S as e,at as t,mn as n}from"./three@0.169.19.js";var r=class{constructor(){this.isPass=!0,this.enabled=!0,this.needsSwap=!0,this.clear=!1,this.renderToScreen=!1}setSize(){}render(){console.error(`THREE.Pass: .render() must be implemented in derived pass.`)}dispose(){}};new n(-1,1,1,-1,0,1),new class extends e{constructor(){super(),this.setAttribute(`position`,new t([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute(`uv`,new t([0,2,0,0,2,0],2))}};export{r as t};
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
+69
View File
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="modulepreload" as="script" href="./assets/three@0.169.19.js">
<link rel="modulepreload" as="script" href="./assets/three-examples@0.169.19.js">
<link rel="modulepreload" as="script" href="./assets/needle-engine@5.0.3.js">
<link rel="preload" as="fetch" fetchpriority="low" href="./assets/MenuScene.glb" type="model/gltf+json" crossorigin>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://www.gstatic.com">
<link rel="preconnect" href="https://cdn.needle.tools">
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&amp;display=swap" crossorigin="" onload="this.rel=&#39;stylesheet&#39;">
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&amp;display=block" crossorigin="" onload="this.rel=&#39;stylesheet&#39;">
<link rel="preload" fetchpriority="high" as="image" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTYwIDE4Ny43NCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iODkuNjQiIHkxPSIxODQuODEiIHgyPSI5MC40OCIgeTI9IjIxLjg1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjNjJkMzk5Ii8+PHN0b3Agb2Zmc2V0PSIuNTEiIHN0b3AtY29sb3I9IiNhY2Q4NDIiLz48c3RvcCBvZmZzZXQ9Ii45IiBzdG9wLWNvbG9yPSIjZDdkYjBhIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIHgxPSI2OS42OCIgeTE9IjE3OC45IiB4Mj0iNjguMDgiIHkyPSIxNi43NyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzBiYTM5OCIvPjxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9IiM0Y2EzNTIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3NmEzMGEiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgeDE9IjM2LjYiIHkxPSIxNTIuMTciIHgyPSIzNC43IiB5Mj0iODQuMTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9Ii4xOSIgc3RvcC1jb2xvcj0iIzM2YTM4MiIvPjxzdG9wIG9mZnNldD0iLjU0IiBzdG9wLWNvbG9yPSIjNDlhNDU5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNzZhMzBiIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIHgxPSIxNS44MiIgeTE9IjE1My4yNCIgeDI9IjE4IiB5Mj0iOTAuODYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMyNjc4ODAiLz48c3RvcCBvZmZzZXQ9Ii41MSIgc3RvcC1jb2xvcj0iIzQ1N2E1YyIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzcxNzUxNiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJlIiB4MT0iMTM1LjA4IiB5MT0iMTM1LjQzIiB4Mj0iMTQ4LjkzIiB5Mj0iNjMuNDciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNiMGQ5MzkiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNlYWRiMDQiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgeDE9Ii00MTYzLjI1IiB5MT0iMjI4NS4xMiIgeDI9Ii00MTYwLjgxIiB5Mj0iMjIxNS4zNCIgZ3JhZGllbnRUcmFuc2Zvcm09InJvdGF0ZSgyMCA0MDg4LjQ5IDEzMzE2LjcxMikiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9Ii4xNyIgc3RvcC1jb2xvcj0iIzc0YWY1MiIvPjxzdG9wIG9mZnNldD0iLjQ4IiBzdG9wLWNvbG9yPSIjOTliZTMyIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjYzBjNDBhIi8+PC9saW5lYXJHcmFkaWVudD48c3ltYm9sIGlkPSJnIiB2aWV3Qm94PSIwIDAgMTYwIDE4Ny43NCI+PHBhdGggc3R5bGU9ImZpbGw6dXJsKCNhKSIgZD0iTTc5LjMyIDM2Ljk4djE1MC43Nkw5NSAxNzQuNTRsNi41OS0xNTYuMzEtMjIuMjcgMTguNzV6Ii8+PHBhdGggc3R5bGU9ImZpbGw6dXJsKCNiKSIgZD0iTTc5LjMyIDM2Ljk4IDU3LjA1IDE4LjIzbDYuNTkgMTU2LjMxIDE1LjY4IDEzLjJWMzYuOTh6Ii8+PHBhdGggc3R5bGU9ImZpbGw6dXJsKCNjKSIgZD0ibTI1LjE5IDEwNC44MyA4LjYzIDQ5LjA0IDEyLjUtMTQuOTUtMi40Ni01Ni40Mi0xOC42NyAyMi4zM3oiLz48cGF0aCBzdHlsZT0iZmlsbDp1cmwoI2QpIiBkPSJNMjUuMTkgMTA0LjgzIDAgOTAuMjRsMTYuOTcgNTMuODYgMTYuODUgOS43Ny04LjYzLTQ5LjA0eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiM5YzMiIGQ9Ik00My44NiA4Mi41IDE4LjY5IDY3Ljk4IDAgOTAuMjRsMjUuMTggMTQuNTlMNDMuODYgODIuNXoiLz48cGF0aCBzdHlsZT0iZmlsbDp1cmwoI2UpIiBkPSJtMTM0LjgyIDc4LjY5LTkuOTcgNTYuNSAxNS41OC05LjA0TDE2MCA2NC4xbC0yNS4xOCAxNC41OXoiLz48cGF0aCBzdHlsZT0iZmlsbDp1cmwoI2YpIiBkPSJtMTM0LjgyIDc4LjY5LTE4LjY4LTIyLjMzLTIuODYgNjUgMTEuNTcgMTMuODMgOS45Ny01Ni41eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmUxMTMiIGQ9Im0xNjAgNjQuMS0xOC42OS0yMi4yNi0yNS4xNyAxNC41MiAxOC42NyAyMi4zM0wxNjAgNjQuMXoiLz48cGF0aCBzdHlsZT0iZmlsbDojZjNlNjAwIiBkPSJNMTAxLjU5IDE4LjIzIDc5LjMyIDAgNTcuMDUgMTguMjNsMjIuMjcgMTguNzUgMjIuMjctMTguNzV6Ii8+PC9zeW1ib2w+PC9kZWZzPjx1c2Ugd2lkdGg9IjE2MCIgaGVpZ2h0PSIxODcuNzQiIHhsaW5rOmhyZWY9IiNnIi8+PC9zdmc+" type="image/svg+xml">
<meta name="og:title" content="Menu Scene">
<meta name="generator" content="Unity 6000.4.3f1, Needle Engine Integration @5.0.3">
<meta name="needle-engine" content="5.0.3">
<meta name="needle:buildtime" content="2026-04-19T20:37:35.867Z">
<meta charset="UTF-8" />
<link rel="icon" href="./assets/favicon.DtN_Fmav.ico">
<meta name="viewport" content="width=device-width, user-scalable=no, viewport-fit=cover">
<title>Menu Scene</title>
<meta name="description" content="🌵 Made with Needle Engine">
<meta property="og:description" content="🌵 Made with Needle Engine" />
<meta name="robots" content="index,follow">
<meta name="url" content="https://needle.tools">
<script type="module" crossorigin src="./assets/index-CkG2vTVa.js"></script>
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime.CYVBeYYp.js">
<link rel="modulepreload" crossorigin href="./assets/three@0.169.19.js">
<link rel="modulepreload" crossorigin href="./assets/materialx.CnHmG--Y.js">
<link rel="modulepreload" crossorigin href="./assets/three-examples@0.169.19.js">
<link rel="modulepreload" crossorigin href="./assets/gltf-progressive.BBJGcb3s.js">
<link rel="modulepreload" crossorigin href="./assets/three-mesh-ui.CgGzZ3ml.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-ui.BzyLX9fs.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-webxr.DQA26K-l.js">
<link rel="modulepreload" crossorigin href="./assets/three-quarks.DALdLWPD.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-particles.Bw3zzNt3.js">
<link rel="modulepreload" crossorigin href="./assets/postprocessing.Wy71DpiM.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.CDv9-f43.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.t1Dx-yNB.js">
<link rel="modulepreload" crossorigin href="./assets/three-mesh-bvh.B-oXEGo2.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine@5.0.3.js">
<link rel="stylesheet" crossorigin href="./assets/index.2XwOwFJz.css">
</head>
<body>
<script>/* needle: fix for peerjs */ window.global = window; var parcelRequire;</script>
<needle-engine>
<div id="asset-picker" class="ar desktop">
<div class="asset-picker__inner">
<button type="button" id="asset-picker-prev" aria-label="Previous model">Previous</button>
<span id="asset-picker-label" class="asset-picker__label"></span>
<span id="asset-picker-index" class="asset-picker__index" aria-live="polite"></span>
<button type="button" id="asset-picker-next" aria-label="Next model">Next</button>
<button type="button" id="asset-picker-ar" aria-label="Start augmented reality">View in AR</button>
</div>
</div>
</needle-engine>
</body>
</html>
Binary file not shown.
+102
View File
@@ -0,0 +1,102 @@
// Needle Engine attributes we want to allow to be overriden
const knownAttributes = [
"src",
"background-color",
"background-image",
"environment-image",
"focus-rect",
];
const scriptUrl = new URL(import.meta.url);
const componentName = scriptUrl.searchParams.get("component-name") || 'needle-app';
if (!customElements.get(componentName)) {
console.debug(`Defining needle-app as <${componentName}>`);
customElements.define(componentName, class extends HTMLElement {
static get observedAttributes() {
return knownAttributes;
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
const template = document.createElement('template');
template.innerHTML = `
<style>
:host {
position: relative;
display: block;
width: max(360px 100%);
height: max(240px, 100%);
margin: 0;
padding: 0;
}
needle-engine {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
`;
this.shadowRoot.appendChild(template.content.cloneNode(true));
const script = document.createElement('script');
script.type = 'module';
const url = new URL('.', import.meta.url);
this.basePath = this.getAttribute('base-path') || `${url.protocol}//${url.host}${url.pathname}`;
while(this.basePath.endsWith('/')) {
this.basePath = this.basePath.slice(0, -1);
}
script.src = this.getAttribute('script-src') || `${this.basePath}/assets/index-CkG2vTVa.js`;
this.shadowRoot.appendChild(script);
this.needleEngine = document.createElement('needle-engine');
this.updateAttributes();
this.shadowRoot.appendChild(this.needleEngine);
console.debug(this.basePath, script.src, this.needleEngine.getAttribute("src"));
}
onConnectedCallback() {
console.debug('NeedleEmbed connected to the DOM');
}
disconnectedCallback() {
console.debug('NeedleEmbed disconnected from the DOM');
}
attributeChangedCallback(name, oldValue, newValue) {
console.debug(`NeedleApp attribute changed: ${name} from ${oldValue} to ${newValue}`);
this.updateAttributes();
}
updateAttributes() {
console.debug("NeedleApp updating attributes");
const src = this.getAttribute('src') || null;
if(src) this.needleEngine.setAttribute("src", src);
else this.needleEngine.removeAttribute("src");
for(const attr of knownAttributes) {
if(attr === "src") continue; // already handled above
if(this.hasAttribute(attr)) {
this.needleEngine.setAttribute(attr, this.getAttribute(attr));
}
else {
this.needleEngine.removeAttribute(attr);
}
}
}
});
}
else {
console.warn(`needle-app <${componentName}> already defined.`);
}
File diff suppressed because one or more lines are too long