From 9fe161ec7cfa2a3c301a392597e778c2a5853c97 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sat, 11 Apr 2026 18:28:31 +0900 Subject: [PATCH] wip --- .../room/objects/dj-player/dj-player.glb | Bin 565100 -> 565192 bytes .../src/utility/room/objects/djPlayer.ts | 87 +++++++++++++++++- packages/frontend/src/utility/room/utility.ts | 14 +++ 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/packages/frontend/assets/room/objects/dj-player/dj-player.glb b/packages/frontend/assets/room/objects/dj-player/dj-player.glb index 481581eba14d8d6bdbf139f4a8864245f7af63d1..e484437a47248a9d032d3ac1ad4b2a23dc772d1e 100644 GIT binary patch delta 2415 zcmZ8he^3LVV;j=;kET;QeRuaH z$NjPMzR&l3&-*>^`+c+bekWYJBDi<&d*XYJWy_XbJM*n&E4QcIJ`N9YyK}_)xG~6` zDh)l|d$3Pvh(<+Wf7jE!LW9uJk?44Q%Z|pz?HwK8Jmz1 ze0;U~H~8UNFXq<#5(Q;G>|1*lFP8hzSMY6gmi1Zrr)B5xqY5ur`Bm^?bFUN6R=kT( z{Q20t?)MHw!b<;jGu-vxFheSE6B~m0$aA@Iihs|__Xsz!v&t4f9()ahm3Drg@}~8r zxae)f(U6GJsx1~iP&H{qJv3!SXSIoa_^{fr;u{Yc$gT0Ad;OcZNwK143TJBb(Y7KV zU({UY;uxxZZ_)06cpe{xZB`ARbHpTk9KOZLXj$RI)yQo;CwVbZH;)$Cwlyfdi<+n{ z=#}R=6}8bXxO$^l>GBwlG`2f1w84YZ@jMJ{-RI7nb<-9!Z`_XldY3W!@Pr#b>nXwe ztzkUhDsl?s?%Fz8iHXAY<{dxS+$1!}iYf|EG$yt*H}BZmA(;#HM?_)I{+>PEy$4N* z;noUl+?$W{Pl|PlmMPVwBuF(q3QTdD!Sw*tp{axstyhwC$y z@oc4*rCiu;E5A;JBT|M^m9vy;bcs?`@bk`c^zT$6nUhhoC!;Q%j2buF3#geRQL{%< zFX2dc8UCDDg{HO$?(Y;GmQKX;Z6aRj4kFkd#;vxngItWX@)&B5pru`;2V~tzm`E=Bn|pKCdI4R{ivuz=qqTG62IemL(f0ldB&SPX8z)PYE=-qVGv)tI2JsTbz_=5e z-X2G5(#-AFUQhCr^SDiGgQ-fCzwO7+%{+XZ8pq!$zkb_~aEeFK9Y6M`d{{8tR3ix^ z8RF>T%Yk5cvS=jDLjSxSR7hbcuZxq^)}kIL~rjl4BZs zr<$u_dF!}hr%Vgz`fr%!uQLnjQH`B_l$6_uTrTUXTF-bFSIbTiO*pQoY_6L4B0pC| zSd(<-aS~tXw|GsJnB2gL-Z=f5escIwZ}YBQ2YV0E-%cmTT`p4ge~0tr%DOIVG26!{ zLF;5)VO{3Q4yy$B>830WO#GJ9uZx)#xz zs?YduO{3Oj$$D-LB-Q1#OOrD(o%DiP`m;)|(84N{ zgEWFy$~dp7jhatH;KIl6S9A0^X6{$#4E~Q@pLNwS|1np9`KMhgXEq&k{q;#E&F2J; dkA$?54=(=N{{h#T9%ldm delta 2391 zcmZuxZBSI_74}^~7%YS-n(Fs{osD?y-Q`PRZG&*K%yZVbQ(;>Krlrc+ccfA zLM9#4rZa%g$nB()+GH>w%DS+IRg;uhO=G7fV@f~b^dtJC&2& zxO2|)p7)&doael|7iOe?{zCFTxogW;J&P7C+I6^KQEJnqH^7*JAnQ&Ku%DJvlZmY1Jr8XhVN;ClHGE|>c;eD4UJzc+xcdsag(EI?~z1yU6ooU!sB7SR#E1!Qck`SSmz& zkr#czgLnPDd;a;HJy$o4w`xi;uxbR) ztqS04^>09{51=$OjobBw_(SMTTnxGWj)sq5DD1}*kr9s;M?rL!$<8!4q95T;Q9nLz zco)BE@Z*&HD~!l~98}(AIuh#N@u=!eZ`8Id#ggW4=WJZJ9<8e%Ob@Q_@!&I~ApN)I zNiS|ZP=VjIMe+8IV)ShFW2`M2)xy$)Ee~&6yHRRXG(9YB*^pS*((>^7$7OzC>%M2 z;-N;<2@(6ZX7A2i$j{8?XF9uUFz1sq7m_ox$yqX2Fg?5N^L!Aq^pzd&d9Y`570y37 zOutRBH-On~Vf?J?5Jx+!(hqf)c;?*adv@n}=)v^w7SjGbqdKmnmSFGc*YNb~0y<6# zNRs_IS#4Cnn@7?p7^}tyuY2JgUWVo|k$e$9B^Ez*T+u4JXTG95Z`rdF?{2GoF;$WcrCs-Cg8>KB;G$R;wQ)M z!3Rf6;GN*UfR+gXH-{t)5w19%MrX1b(FvE+NKzzU!Y6drJ5huB6V=r-c&!k8hGa&BF+GJBP6>D*!$X#pR9O7ArFEHSJMa-1bpoT(Mu}iOF*2qi9?;?aAeY z|5eF~7ZcV@)jnIs>h0ZCY#G0=yF59}(G}Ge*AmSsLV3EP6RSOWEM)(?inCN=hKc@L zA^STk9B67P*4_%+&#vIT6q8C5laQUEaIUUcihX@K6>DATge@AQ|34wSPjsU(tf5?v zDA$U|s1ya8h?Np|3Ww%~P~t|+W|dTUpWvj%W40sa_XVeLoMs^HnsQWGb%w{`+r&qe zb(IT6I}rIj!f{s%j&liHZkg5)TbiTN==}vO;+N^q~ zoz>1Y!(9wVxvCOVY*x;~hXz?Obx>k+Q#d0M1p6Z5w9nC1(!G+@a3)k$UBOur!!4u6 zjJqgDRZT}3dO1Xk_P3o;nma2&%hAbILe*qj@Xbj~6KNWsC~Ut}%Xh142G4aNvD4j` z60+Z~<(jK8(#P4CcO{oqH8uMxZ{_ZbI`Qp>>_LjsZA*3;zp{ZX^Qe}6wU$Nk*-d&> zs- { + createInstance: async ({ model, options, scene }) => { + const screenMesh = model.findMesh('__X_SCREEN__'); + const screenMaterial = model.findMaterial('__X_SCREEN__'); + const defaultScreenTexture = screenMaterial.emissiveTexture; + + normalizeUvToSquare(screenMesh); + const updateUv = createPlaneUvMapper(screenMesh); + + const applyFit = () => { + const tex = screenMaterial.emissiveTexture; + if (tex == null) return; + + const srcAspect = tex.getSize().width / tex.getSize().height; + const targetAspect = 15.6 / 8.33; + + updateUv(srcAspect, targetAspect, options.fit); + + model.updated(); + }; + + applyFit(); + + const applyCustomPicture = () => new Promise((resolve) => { + if (options.customPicture != null && options.customPicture !== '') { + const tex = new BABYLON.Texture(options.customPicture, scene, false, false); + tex.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE; + tex.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE; + tex.level = 0.5; + + screenMaterial.unfreeze(); + screenMaterial.emissiveTexture = tex; + + tex.onLoadObservable.addOnce(() => { + applyFit(); + resolve(); + }); + } else { + screenMaterial.emissiveTexture = defaultScreenTexture; + applyFit(); + resolve(); + } + }); + + await applyCustomPicture(); + + const applyScreenBrightness = () => { + const b = options.screenBrightness; + screenMaterial.emissiveColor = new BABYLON.Color3(b, b, b); + }; + + applyScreenBrightness(); + return { + onOptionsUpdated: ([k, v]) => { + switch (k) { + case 'screenBrightness': applyScreenBrightness(); break; + case 'customPicture': applyCustomPicture(); break; + case 'fit': applyFit(); break; + } + }, interactions: {}, }; }, diff --git a/packages/frontend/src/utility/room/utility.ts b/packages/frontend/src/utility/room/utility.ts index be2dd097fb..d8bc9caebd 100644 --- a/packages/frontend/src/utility/room/utility.ts +++ b/packages/frontend/src/utility/room/utility.ts @@ -376,6 +376,20 @@ export function getPlaneUvIndexes(mesh: BABYLON.Mesh) { return [aIndex, bIndex, cIndex, dIndex]; } +export function normalizeUvToSquare(mesh: BABYLON.Mesh) { + const uvs = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; + const uvIndexes = getPlaneUvIndexes(mesh); + uvs[uvIndexes[0]] = 0; + uvs[uvIndexes[0] + 1] = 0; + uvs[uvIndexes[1]] = 1; + uvs[uvIndexes[1] + 1] = 0; + uvs[uvIndexes[2]] = 0; + uvs[uvIndexes[2] + 1] = 1; + uvs[uvIndexes[3]] = 1; + uvs[uvIndexes[3] + 1] = 1; + mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs); +} + export function createPlaneUvMapper(mesh: BABYLON.Mesh) { mesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true);