fix(menu): load pizza GLB at runtime when scene export has no mesh

Exported MenuScene.glb had cc0_-_pizza_salami with MeshRenderer but null
materials and no glTF mesh buffers (common when Unity imported an LFS pointer).
Add include/dishes standalone GLB and dishMeshFallback to GLTFLoader-inject
geometry when a dish root has no meshes. Track include/dishes outside Git LFS.

Made-with: Cursor
This commit is contained in:
pelpanagiotis
2026-04-20 00:07:33 +03:00
parent 0200cd8082
commit 400b6d6f09
37 changed files with 86 additions and 21 deletions
+3
View File
@@ -13,3 +13,6 @@
# Vite/Needle dist/ is static hosting: must be real binaries, not LFS pointers (breaks fetch/GLTF load). # Vite/Needle dist/ is static hosting: must be real binaries, not LFS pointers (breaks fetch/GLTF load).
Needle/**/dist/** -filter -diff -merge Needle/**/dist/** -filter -diff -merge
# Runtime GLB fallbacks (copied for web): must be real files so fetch/GLTFLoader works without LFS checkout.
Needle/**/include/dishes/** -filter -diff -merge
Binary file not shown.
-2
View File
@@ -1,2 +0,0 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./register_types.JDIhnf6T.js","./needle-engine-webxr.DDCPc9_g.js","./materialx.CnHmG--Y.js","./rolldown-runtime.CYVBeYYp.js","./three@0.169.19.js","./needle-engine-ui.iRWmt52F.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.D0CNgtSQ.js","./needle-engine-particles.B21Zru40.js","./three-quarks.DALdLWPD.js","./needle-engine.extras.D-PG1GOa.js","./postprocessing.Wy71DpiM.js","./three-mesh-bvh.B-oXEGo2.js","./needle-engine.Bq13_677.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.iRWmt52F.js";import"./needle-engine@5.0.3.js";import{x as i}from"./needle-engine-webxr.DDCPc9_g.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.JDIhnf6T.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`,`1776632064266`),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.Bq13_677.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.
+2
View File
@@ -0,0 +1,2 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./register_types.CeurxO3a.js","./needle-engine-webxr.BfNO-tft.js","./materialx.CnHmG--Y.js","./rolldown-runtime.CYVBeYYp.js","./three@0.169.19.js","./needle-engine-ui.i2hfjKja.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.CWxm8YHB.js","./needle-engine-particles.Bz_Ei_ja.js","./three-quarks.DALdLWPD.js","./needle-engine.extras.1SuflpgE.js","./postprocessing.Wy71DpiM.js","./three-mesh-bvh.B-oXEGo2.js","./needle-engine.HinF1QFy.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.i2hfjKja.js";import{A as i}from"./three-examples@0.169.19.js";import"./needle-engine@5.0.3.js";import{x as a}from"./needle-engine-webxr.BfNO-tft.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.CeurxO3a.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]),import.meta.url);var o=[];globalThis[`needle:codegen_files`]=o,o.push(`./assets/MenuScene.glb`),document.addEventListener(`DOMContentLoaded`,()=>{let e=document.querySelector(`needle-engine`);e&&e.getAttribute(`src`)===null&&(e.setAttribute(`hash`,`1776632327654`),e.setAttribute(`src`,JSON.stringify(o)))}),console.log(`Made with ♥ by 🌵 Needle - https://needle.tools — Version 5.0.3`);var s={"cc0_-_pizza_salami":`include/dishes/cc0_-_pizza_salami.glb`};function c(e){let t=0;return e.traverse(e=>{e.isMesh&&(t+=1)}),t}function l(e){let t=`./`.endsWith(`/`)?`./`:`.//`;return new URL(e,new URL(t,window.location.href)).href}async function u(e){let t=new i;for(let n of e.dishes){if(!n)continue;let e=s[n.name];if(!e||c(n)>0)continue;let r=l(e),i=await t.loadAsync(r);i.scene.name=`${n.name}_mesh`,n.add(i.scene)}}function d(){let e=document.querySelector(`needle-engine`);if(!e)return;let n=async()=>{try{let n=await e.getContext(),r=t(MenuController,n);r&&await u(r)}catch(e){console.warn(`[dishMeshFallback] Could not inject dish meshes:`,e)}};e.addEventListener(`loadfinished`,()=>void n())}d(),r(e=>{let t=e.scene.getComponentInChildren(a);t||(t=e.scene.addComponent(a),t.createARButton=!0,t.createVRButton=!0),t.autoPlace=!0,t.autoCenter=!0,t.arScale=1});function f(e){document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>e(),{once:!0}):e()}function p(){let e=document.querySelector(`needle-engine`),r=document.querySelector(`#asset-picker-prev`),i=document.querySelector(`#asset-picker-next`),a=document.querySelector(`#asset-picker-ar`),o=document.querySelector(`#asset-picker-label`),s=document.querySelector(`#asset-picker-index`);if(!e||!r||!i||!a||!o||!s)return;let c=null,l=!1,u=!1,d=!1,p=()=>{c&&c.getDishSlotCount()>0?(o.textContent=c.getPickerLabel(),s.textContent=``):c?(o.textContent=`Menu (assign dishes in Unity)`,s.textContent=``):(o.textContent=`Menu scene`,s.textContent=``);let e=c!==null&&c.getDishSlotCount()>1;r.disabled=!e,i.disabled=!e,a.disabled=!u||d||l},m=async()=>{try{let n=await e.getContext();c=t(MenuController,n)}catch{c=null}p()};n.isARSupported().then(e=>{u=e,p()});let h=e=>{!c||c.getDishSlotCount()<=1||(e<0?c.selectPreviousDish():c.selectNextDish(),p())},g=async()=>{if(!(!u||d||l)){d=!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{d=!1,p()}}};r.addEventListener(`click`,()=>h(-1)),i.addEventListener(`click`,()=>h(1)),a.addEventListener(`click`,()=>void g()),e.addEventListener(`enter-ar`,()=>{l=!0,p()}),e.addEventListener(`exit-ar`,()=>{l=!1,p()}),e.addEventListener(`enter-vr`,()=>{l=!0,p()}),e.addEventListener(`exit-vr`,()=>{l=!1,p()}),e.addEventListener(`loadfinished`,()=>void m()),f(()=>{requestAnimationFrame(()=>void m())})}p(),e(()=>import(`./needle-engine.HinF1QFy.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.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
import{n as e}from"./rolldown-runtime.CYVBeYYp.js";import{A as t,Ar as n,Bt as r,F as i,Fr as a,Ft as o,Nt as s,On as c,Rr as l,S as u,St as ee,Xt as te,Zt as ne,_ as re,c as ie,fn as d,gn as f,gr as ae,hn as oe,in as se,tt as ce,wn as le,x as p}from"./three@0.169.19.js";import{$ as ue,$a as de,$i as fe,A as pe,Br as me,C as he,Ci as ge,Cn as _e,D as ve,Da as ye,Di as be,Dn as xe,Dt as Se,E as Ce,En as we,G as Te,Gi as Ee,Gr as De,Gt as Oe,H as m,Hn as ke,Ho as Ae,Ii as je,J as Me,Ja as Ne,Ji as Pe,Jr as Fe,Ka as h,Kr as Ie,L as Le,La as Re,Lr as ze,M as Be,Mi as Ve,Na as He,O as Ue,Oi as We,On as Ge,Ot as Ke,P as qe,Pi as Je,Pn as Ye,Q as Xe,Qi as Ze,Ro as Qe,S as $e,Si as et,T as tt,Ti as nt,Tn as rt,Tt as it,Ua as g,Uo as at,Ut as ot,V as st,Vn as ct,Wi as lt,Wo as ut,X as _,Xa as dt,Xr as ft,Y as pt,Yr as mt,Z as ht,_ as gt,_a as v,_n as _t,a as vt,ai as yt,b as bt,ba as y,bi as xt,co as b,ct as x,d as St,dn as S,eo as C,f as Ct,fn as wt,g as Tt,gi as Et,gr as w,h as Dt,ht as Ot,i as kt,j as At,ja as jt,ji as Mt,jo as Nt,jt as Pt,k as Ft,kn as It,l as Lt,n as Rt,na as zt,o as Bt,ot as Vt,p as Ht,q as Ut,qr as T,r as Wt,ra as E,s as Gt,st as Kt,t as qt,ti as D,u as Jt,un as O,v as Yt,va as k,vi as Xt,w as Zt,wi as Qt,wn as $t,x as en,xi as tn,y as nn,yi as rn,za as an}from"./needle-engine-ui.iRWmt52F.js";import{A,d as on,j as sn,n as cn,t as ln}from"./three-examples@0.169.19.js";import{$ as un,A as dn,B as fn,Bt as pn,C as mn,Ct as hn,D as gn,Dt as _n,E as vn,Et as yn,F as bn,G as xn,Gt as Sn,H as Cn,I as wn,It as Tn,J as En,Jt as Dn,K as On,Kt as kn,L as An,Nt as jn,O as Mn,Ot as Nn,P as Pn,Q as Fn,Qt as In,R as Ln,Rt as Rn,S as zn,St as Bn,T as Vn,U as Hn,Ut as Un,V as Wn,Vt as Gn,W as Kn,Wt as qn,X as Jn,Xt as Yn,Y as Xn,Z as Zn,Zt as Qn,_ as $n,_t as er,a as tr,at as nr,b as rr,bt as ir,cn as ar,d as or,et as sr,f as cr,fn as lr,g as ur,h as dr,i as fr,it as pr,k as mr,kt as hr,ln as gr,m as _r,mn as vr,n as yr,nt as br,o as xr,ot as Sr,p as Cr,pn as wr,q as Tr,qt as Er,r as Dr,rt as Or,sn as kr,t as Ar,tt as jr,v as Mr,vt as Nr,w as Pr,wt as Fr,x as Ir,xt as Lr,y as Rr,yt as zr,z as Br,zt as Vr}from"./needle-engine-webxr.DDCPc9_g.js";import{A as Hr,B as Ur,C as Wr,Ct as Gr,D as Kr,E as qr,Et as Jr,F as Yr,G as Xr,H as Zr,I as Qr,K as $r,L as ei,M as ti,Mt as ni,N as ri,Nt as ii,O as ai,P as oi,Q as si,R as ci,S as li,St as ui,T as di,Tt as fi,U as pi,V as mi,W as hi,X as gi,_ as _i,_t as vi,a as yi,at as bi,b as xi,bt as Si,c as Ci,ct as wi,d as Ti,dt as Ei,f as Di,ft as Oi,g as ki,gt as Ai,h as ji,ht as Mi,i as Ni,it as Pi,j as Fi,jt as Ii,k as Li,l as Ri,lt as zi,m as Bi,mt as Vi,n as Hi,nt as Ui,o as Wi,ot as Gi,p as Ki,pt as qi,q as Ji,r as Yi,s as Xi,st as Zi,t as Qi,u as $i,ut as ea,v as ta,vt as na,w as ra,wt as ia,x as aa,xt as oa,y as sa,yt as ca,z as la}from"./needle-engine.extras.D0CNgtSQ.js";import{C as ua,D as da,E as fa,S as pa,T as ma,a as ha,b as ga,c as _a,d as va,f as ya,g as ba,h as xa,i as Sa,l as Ca,m as wa,o as Ta,p as Ea,r as Da,s as Oa,t as ka,u as Aa,v as ja,w as Ma,x as Na,y as Pa}from"./needle-engine-particles.B21Zru40.js";import{a as Fa,c as Ia,d as La,f as Ra,g as za,h as Ba,i as Va,l as Ha,m as Ua,n as Wa,o as Ga,p as Ka,r as qa,s as Ja,t as Ya,u as Xa,y as Za}from"./needle-engine.extras.D-PG1GOa.js";import{a as Qa,t as $a}from"./three-mesh-bvh.B-oXEGo2.js";var j=void 0,M=null,N=null,P=!1,eo=null,to=`terminal`;b(`console`)&&ro();var no=Symbol(`consoleParent`);function ro(){if(j){j.showSwitch();return}uo()}function io(){j&&(j.hide(),j.hideSwitch())}function ao(){eo||=setInterval(so,500)}var oo=0;function so(){let e=dt(),t=e!==oo;oo=e,t&&co()}function co(){ro(),N&&(N.setAttribute(`error`,`true`),N.innerText=`🤬`)}function lo(){N&&(N.removeAttribute(`error`),N.innerText=to)}function uo(e=!1){if(j!==void 0||P)return;P=!0;let t=document.createElement(`script`);t.onload=()=>{if(!globalThis.VConsole){console.warn(`🌵 Debug console failed to load.`),P=!1,j=null;return}P=!1,ao(),j=new VConsole({pluginOrder:[`default`,`needle-console`]});let t=globalThis[`needle:codegen_files`];if(t&&t.length>0&&j.addPlugin(fo()),j.addPlugin(bo()),j.addPlugin(xo()),M=No(),M&&(M[no]=M.parentElement,M.style.position=`absolute`,M.style.zIndex=(2**53-1).toString()),j.setSwitchPosition(20,30),N=Mo(),N){N.innerText=to,N.addEventListener(`click`,lo);let t=document.createElement(`style`);t.innerHTML=` import{n as e}from"./rolldown-runtime.CYVBeYYp.js";import{A as t,Ar as n,Bt as r,F as i,Fr as a,Ft as o,Nt as s,On as c,Rr as l,S as u,St as ee,Xt as te,Zt as ne,_ as re,c as ie,fn as d,gn as f,gr as ae,hn as oe,in as se,tt as ce,wn as le,x as p}from"./three@0.169.19.js";import{$ as ue,$a as de,$i as fe,A as pe,Br as me,C as he,Ci as ge,Cn as _e,D as ve,Da as ye,Di as be,Dn as xe,Dt as Se,E as Ce,En as we,G as Te,Gi as Ee,Gr as De,Gt as Oe,H as m,Hn as ke,Ho as Ae,Ii as je,J as Me,Ja as Ne,Ji as Pe,Jr as Fe,Ka as h,Kr as Ie,L as Le,La as Re,Lr as ze,M as Be,Mi as Ve,Na as He,O as Ue,Oi as We,On as Ge,Ot as Ke,P as qe,Pi as Je,Pn as Ye,Q as Xe,Qi as Ze,Ro as Qe,S as $e,Si as et,T as tt,Ti as nt,Tn as rt,Tt as it,Ua as g,Uo as at,Ut as ot,V as st,Vn as ct,Wi as lt,Wo as ut,X as _,Xa as dt,Xr as ft,Y as pt,Yr as mt,Z as ht,_ as gt,_a as v,_n as _t,a as vt,ai as yt,b as bt,ba as y,bi as xt,co as b,ct as x,d as St,dn as S,eo as C,f as Ct,fn as wt,g as Tt,gi as Et,gr as w,h as Dt,ht as Ot,i as kt,j as At,ja as jt,ji as Mt,jo as Nt,jt as Pt,k as Ft,kn as It,l as Lt,n as Rt,na as zt,o as Bt,ot as Vt,p as Ht,q as Ut,qr as T,r as Wt,ra as E,s as Gt,st as Kt,t as qt,ti as D,u as Jt,un as O,v as Yt,va as k,vi as Xt,w as Zt,wi as Qt,wn as $t,x as en,xi as tn,y as nn,yi as rn,za as an}from"./needle-engine-ui.i2hfjKja.js";import{A,d as on,j as sn,n as cn,t as ln}from"./three-examples@0.169.19.js";import{$ as un,A as dn,B as fn,Bt as pn,C as mn,Ct as hn,D as gn,Dt as _n,E as vn,Et as yn,F as bn,G as xn,Gt as Sn,H as Cn,I as wn,It as Tn,J as En,Jt as Dn,K as On,Kt as kn,L as An,Nt as jn,O as Mn,Ot as Nn,P as Pn,Q as Fn,Qt as In,R as Ln,Rt as Rn,S as zn,St as Bn,T as Vn,U as Hn,Ut as Un,V as Wn,Vt as Gn,W as Kn,Wt as qn,X as Jn,Xt as Yn,Y as Xn,Z as Zn,Zt as Qn,_ as $n,_t as er,a as tr,at as nr,b as rr,bt as ir,cn as ar,d as or,et as sr,f as cr,fn as lr,g as ur,h as dr,i as fr,it as pr,k as mr,kt as hr,ln as gr,m as _r,mn as vr,n as yr,nt as br,o as xr,ot as Sr,p as Cr,pn as wr,q as Tr,qt as Er,r as Dr,rt as Or,sn as kr,t as Ar,tt as jr,v as Mr,vt as Nr,w as Pr,wt as Fr,x as Ir,xt as Lr,y as Rr,yt as zr,z as Br,zt as Vr}from"./needle-engine-webxr.BfNO-tft.js";import{A as Hr,B as Ur,C as Wr,Ct as Gr,D as Kr,E as qr,Et as Jr,F as Yr,G as Xr,H as Zr,I as Qr,K as $r,L as ei,M as ti,Mt as ni,N as ri,Nt as ii,O as ai,P as oi,Q as si,R as ci,S as li,St as ui,T as di,Tt as fi,U as pi,V as mi,W as hi,X as gi,_ as _i,_t as vi,a as yi,at as bi,b as xi,bt as Si,c as Ci,ct as wi,d as Ti,dt as Ei,f as Di,ft as Oi,g as ki,gt as Ai,h as ji,ht as Mi,i as Ni,it as Pi,j as Fi,jt as Ii,k as Li,l as Ri,lt as zi,m as Bi,mt as Vi,n as Hi,nt as Ui,o as Wi,ot as Gi,p as Ki,pt as qi,q as Ji,r as Yi,s as Xi,st as Zi,t as Qi,u as $i,ut as ea,v as ta,vt as na,w as ra,wt as ia,x as aa,xt as oa,y as sa,yt as ca,z as la}from"./needle-engine.extras.CWxm8YHB.js";import{C as ua,D as da,E as fa,S as pa,T as ma,a as ha,b as ga,c as _a,d as va,f as ya,g as ba,h as xa,i as Sa,l as Ca,m as wa,o as Ta,p as Ea,r as Da,s as Oa,t as ka,u as Aa,v as ja,w as Ma,x as Na,y as Pa}from"./needle-engine-particles.Bz_Ei_ja.js";import{a as Fa,c as Ia,d as La,f as Ra,g as za,h as Ba,i as Va,l as Ha,m as Ua,n as Wa,o as Ga,p as Ka,r as qa,s as Ja,t as Ya,u as Xa,y as Za}from"./needle-engine.extras.1SuflpgE.js";import{a as Qa,t as $a}from"./three-mesh-bvh.B-oXEGo2.js";var j=void 0,M=null,N=null,P=!1,eo=null,to=`terminal`;b(`console`)&&ro();var no=Symbol(`consoleParent`);function ro(){if(j){j.showSwitch();return}uo()}function io(){j&&(j.hide(),j.hideSwitch())}function ao(){eo||=setInterval(so,500)}var oo=0;function so(){let e=dt(),t=e!==oo;oo=e,t&&co()}function co(){ro(),N&&(N.setAttribute(`error`,`true`),N.innerText=`🤬`)}function lo(){N&&(N.removeAttribute(`error`),N.innerText=to)}function uo(e=!1){if(j!==void 0||P)return;P=!0;let t=document.createElement(`script`);t.onload=()=>{if(!globalThis.VConsole){console.warn(`🌵 Debug console failed to load.`),P=!1,j=null;return}P=!1,ao(),j=new VConsole({pluginOrder:[`default`,`needle-console`]});let t=globalThis[`needle:codegen_files`];if(t&&t.length>0&&j.addPlugin(fo()),j.addPlugin(bo()),j.addPlugin(xo()),M=No(),M&&(M[no]=M.parentElement,M.style.position=`absolute`,M.style.zIndex=(2**53-1).toString()),j.setSwitchPosition(20,30),N=Mo(),N){N.innerText=to,N.addEventListener(`click`,lo);let t=document.createElement(`style`);t.innerHTML=`
#__vconsole .vc-switch { #__vconsole .vc-switch {
border: 1px solid rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .1);
border-radius: 50%; border-radius: 50%;
Binary file not shown.
@@ -1,4 +1,4 @@
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.iRWmt52F.js";import"./needle-engine@5.0.3.js";import{m as u}from"./needle-engine-webxr.DDCPc9_g.js";import{m as d,t as f}from"./needle-engine.extras.D-PG1GOa.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=` 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.i2hfjKja.js";import"./needle-engine@5.0.3.js";import{m as u}from"./needle-engine-webxr.BfNO-tft.js";import{m as d,t as f}from"./needle-engine.extras.1SuflpgE.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; position: absolute;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7 -7
View File
@@ -22,7 +22,7 @@
<meta name="og:title" content="Menu Scene"> <meta name="og:title" content="Menu Scene">
<meta name="generator" content="Unity 6000.4.3f1, Needle Engine Integration @5.0.3"> <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-engine" content="5.0.3">
<meta name="needle:buildtime" content="2026-04-19T20:57:04.006Z"> <meta name="needle:buildtime" content="2026-04-19T21:06:00.619Z">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="./assets/favicon.DtN_Fmav.ico"> <link rel="icon" href="./assets/favicon.DtN_Fmav.ico">
@@ -37,20 +37,20 @@
<meta name="robots" content="index,follow"> <meta name="robots" content="index,follow">
<meta name="url" content="https://localhost:3000"> <meta name="url" content="https://localhost:3000">
<script type="module" crossorigin src="./assets/index-C4yn7lK8.js"></script> <script type="module" crossorigin src="./assets/index-Fs2VLbun.js"></script>
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime.CYVBeYYp.js"> <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/three@0.169.19.js">
<link rel="modulepreload" crossorigin href="./assets/materialx.CnHmG--Y.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/three-examples@0.169.19.js">
<link rel="modulepreload" crossorigin href="./assets/gltf-progressive.BBJGcb3s.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/three-mesh-ui.CgGzZ3ml.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-ui.iRWmt52F.js"> <link rel="modulepreload" crossorigin href="./assets/needle-engine-ui.i2hfjKja.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-webxr.DDCPc9_g.js"> <link rel="modulepreload" crossorigin href="./assets/needle-engine-webxr.BfNO-tft.js">
<link rel="modulepreload" crossorigin href="./assets/three-quarks.DALdLWPD.js"> <link rel="modulepreload" crossorigin href="./assets/three-quarks.DALdLWPD.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine-particles.B21Zru40.js"> <link rel="modulepreload" crossorigin href="./assets/needle-engine-particles.Bz_Ei_ja.js">
<link rel="modulepreload" crossorigin href="./assets/postprocessing.Wy71DpiM.js"> <link rel="modulepreload" crossorigin href="./assets/postprocessing.Wy71DpiM.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.D-PG1GOa.js"> <link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.1SuflpgE.js">
<link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.D0CNgtSQ.js"> <link rel="modulepreload" crossorigin href="./assets/needle-engine.extras.CWxm8YHB.js">
<link rel="modulepreload" crossorigin href="./assets/three-mesh-bvh.B-oXEGo2.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="modulepreload" crossorigin href="./assets/needle-engine@5.0.3.js">
<link rel="stylesheet" crossorigin href="./assets/index.2XwOwFJz.css"> <link rel="stylesheet" crossorigin href="./assets/index.2XwOwFJz.css">
Binary file not shown.
+1 -1
View File
@@ -53,7 +53,7 @@ if (!customElements.get(componentName)) {
while(this.basePath.endsWith('/')) { while(this.basePath.endsWith('/')) {
this.basePath = this.basePath.slice(0, -1); this.basePath = this.basePath.slice(0, -1);
} }
script.src = this.getAttribute('script-src') || `${this.basePath}/assets/index-C4yn7lK8.js`; script.src = this.getAttribute('script-src') || `${this.basePath}/assets/index-Fs2VLbun.js`;
this.shadowRoot.appendChild(script); this.shadowRoot.appendChild(script);
this.needleEngine = document.createElement('needle-engine'); this.needleEngine = document.createElement('needle-engine');
File diff suppressed because one or more lines are too long
+61
View File
@@ -0,0 +1,61 @@
import { findObjectOfType } from "@needle-tools/engine";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { Object3D } from "three";
import type { MenuController } from "./scripts/MenuController.js";
/**
* When Unity/Needle exports a dish root without glTF mesh data (e.g. GLB was a Git LFS pointer
* at import time), inject geometry from a bundled standalone GLB matching the object name.
*/
const DISH_GLBS: Record<string, string> = {
"cc0_-_pizza_salami": "include/dishes/cc0_-_pizza_salami.glb",
};
function countRenderableMeshes(root: Object3D): number {
let n = 0;
root.traverse((o) => {
const m = o as Object3D & { isMesh?: boolean };
if (m.isMesh) n += 1;
});
return n;
}
function resolveIncludeUrl(relative: string): string {
const base = import.meta.env.BASE_URL ?? "./";
const normalized = base.endsWith("/") ? base : `${base}/`;
return new URL(relative, new URL(normalized, window.location.href)).href;
}
async function ensureDishMeshes(menu: MenuController): Promise<void> {
const loader = new GLTFLoader();
for (const dish of menu.dishes) {
if (!dish) continue;
const rel = DISH_GLBS[dish.name];
if (!rel) continue;
if (countRenderableMeshes(dish) > 0) continue;
const url = resolveIncludeUrl(rel);
const gltf = await loader.loadAsync(url);
gltf.scene.name = `${dish.name}_mesh`;
dish.add(gltf.scene);
}
}
function initDishMeshFallback(): void {
const needle = document.querySelector("needle-engine");
if (!needle) return;
const run = async (): Promise<void> => {
try {
const ctx = await needle.getContext();
const menu = findObjectOfType(MenuController, ctx);
if (menu) await ensureDishMeshes(menu);
} catch (err) {
console.warn("[dishMeshFallback] Could not inject dish meshes:", err);
}
};
needle.addEventListener("loadfinished", () => void run());
}
initDishMeshFallback();
+1
View File
@@ -1,3 +1,4 @@
import("@needle-tools/engine") /* async import of needle engine */; import("@needle-tools/engine") /* async import of needle engine */;
import "./dishMeshFallback";
import "./enableXR"; import "./enableXR";
import "./assetPicker"; import "./assetPicker";