From 0a6bfce548bfa607ceea219db39688d5a88ef4fa Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Thu, 28 May 2026 17:32:45 +0900 Subject: [PATCH] wip --- .../src/PlayerContainer.ts | 19 +++++++----- .../src/avatars/accessories/mug.ts | 29 ++++++++++++++++-- .../src/avatars/accessory.ts | 2 +- .../world/avatar-accessories/mug/steam.png | Bin 0 -> 3632 bytes 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 packages/frontend/assets/world/avatar-accessories/mug/steam.png diff --git a/packages/frontend-misskey-world-engine/src/PlayerContainer.ts b/packages/frontend-misskey-world-engine/src/PlayerContainer.ts index d8aea3bd67..5eb291d92e 100644 --- a/packages/frontend-misskey-world-engine/src/PlayerContainer.ts +++ b/packages/frontend-misskey-world-engine/src/PlayerContainer.ts @@ -47,7 +47,8 @@ export class PlayerContainer { public id: string; private profile: PlayerProfile; private root: BABYLON.TransformNode; - private modelRootContainerForAnim: BABYLON.TransformNode; + private subRootContainerForAnim: BABYLON.TransformNode; + private subRoot: BABYLON.TransformNode; private modelRoot: BABYLON.TransformNode | null = null; private sr: BABYLON.SnapshotRenderingHelper; private scene: BABYLON.Scene; @@ -63,8 +64,10 @@ export class PlayerContainer { this.root = new BABYLON.TransformNode(`player:${this.id}`, params.scene); this.root.rotationQuaternion = null; - this.modelRootContainerForAnim = new BABYLON.TransformNode(`player:${this.id}:modelRootContainerForAnim`, params.scene); - this.modelRootContainerForAnim.parent = this.root; + this.subRootContainerForAnim = new BABYLON.TransformNode(`player:${this.id}:subRootContainerForAnim`, params.scene); + this.subRootContainerForAnim.parent = this.root; + this.subRoot = new BABYLON.TransformNode(`player:${this.id}:subRoot`, params.scene); + this.subRoot.parent = this.subRootContainerForAnim; if (params.state) this.applyState(params.state, true); } @@ -77,7 +80,7 @@ export class PlayerContainer { // meshじゃなくtransform nodeにしてパフォーマンス向上 this.modelRoot = new BABYLON.TransformNode('__root__', this.scene); - this.modelRoot.parent = this.modelRootContainerForAnim; + this.modelRoot.parent = this.subRoot; this.modelRoot.scaling.x = -1; this.modelRoot.scaling = this.modelRoot.scaling.scale(WORLD_SCALE);// cmをmに @@ -171,11 +174,11 @@ export class PlayerContainer { { frame: 90, value: cm(2) }, { frame: 120, value: cm(0) }, ]); - this.modelRootContainerForAnim.animations = [anim]; + this.subRootContainerForAnim.animations = [anim]; this.animationObserver = this.scene.onAfterAnimationsObservable.add(() => { - this.sr.updateMesh(this.modelRootContainerForAnim.getChildMeshes(), false); + this.sr.updateMesh(this.subRootContainerForAnim.getChildMeshes(), false); }); - this.scene.beginAnimation(this.modelRootContainerForAnim, 0, 120, true); + this.scene.beginAnimation(this.subRootContainerForAnim, 0, 120, true); } private async loadAccessory(args: { @@ -205,6 +208,8 @@ export class PlayerContainer { await container.load(); + container.root.parent = this.subRoot; + return container; } diff --git a/packages/frontend-misskey-world-engine/src/avatars/accessories/mug.ts b/packages/frontend-misskey-world-engine/src/avatars/accessories/mug.ts index 99b86df18d..4b91e0fe7d 100644 --- a/packages/frontend-misskey-world-engine/src/avatars/accessories/mug.ts +++ b/packages/frontend-misskey-world-engine/src/avatars/accessories/mug.ts @@ -7,15 +7,38 @@ import * as BABYLON from '@babylonjs/core'; import { cm } from 'misskey-world/src/utility.js'; import { mug_schema } from 'misskey-world/src/room/objects/mug.schema.js'; import { defineAccessory } from '../accessory.js'; -import { yuge } from '../utility.js'; export const mug = defineAccessory(mug_schema, { createInstance: ({ scene, root, sr }) => { - const yugeDispose = yuge(scene, root, new BABYLON.Vector3(0, cm(5), 0), sr); + const emitter = new BABYLON.TransformNode('emitter', scene); + emitter.parent = root; + emitter.position = new BABYLON.Vector3(0, cm(5), 0); + const ps = new BABYLON.ParticleSystem('steamParticleSystem', 8, scene); + ps.particleTexture = new BABYLON.Texture('/client-assets/world/avatar-accessories/mug/steam.png'); + ps.emitter = emitter; + ps.minEmitBox = new BABYLON.Vector3(cm(-1), 0, cm(-1)); + ps.maxEmitBox = new BABYLON.Vector3(cm(1), 0, cm(1)); + ps.minEmitPower = cm(10); + ps.maxEmitPower = cm(12); + ps.minLifeTime = 2; + ps.maxLifeTime = 3; + ps.addSizeGradient(0, cm(10), cm(12)); + ps.addSizeGradient(1, cm(18), cm(20)); + ps.direction1 = new BABYLON.Vector3(-0.3, 1, 0.3); + ps.direction2 = new BABYLON.Vector3(0.3, 1, -0.3); + ps.emitRate = 0.5; + ps.blendMode = BABYLON.ParticleSystem.BLENDMODE_ADD; + ps.color1 = new BABYLON.Color4(1, 1, 1, 0.3); + ps.color2 = new BABYLON.Color4(1, 1, 1, 0.2); + ps.colorDead = new BABYLON.Color4(1, 1, 1, 0); + ps.preWarmCycles = Math.random() * 1000; + ps.start(); + sr.fixParticleSystem(ps); return { dispose: () => { - yugeDispose?.(); + ps.stop(); + emitter.dispose(); }, }; }, diff --git a/packages/frontend-misskey-world-engine/src/avatars/accessory.ts b/packages/frontend-misskey-world-engine/src/avatars/accessory.ts index 0a4fa569cb..044f36120f 100644 --- a/packages/frontend-misskey-world-engine/src/avatars/accessory.ts +++ b/packages/frontend-misskey-world-engine/src/avatars/accessory.ts @@ -39,6 +39,6 @@ export function defineAccessorySchema>(schema: Schema, def: Pick, 'path' | 'createInstance'>): AccessoryDef { +export function defineAccessory>(schema: Schema, def: Pick, 'path' | 'createInstance'>): AvatarAccessoryDef { return { ...schema, ...def }; } diff --git a/packages/frontend/assets/world/avatar-accessories/mug/steam.png b/packages/frontend/assets/world/avatar-accessories/mug/steam.png new file mode 100644 index 0000000000000000000000000000000000000000..d088cd71cfae88ccde5886346a468fbd328e1722 GIT binary patch literal 3632 zcma)9dpy(o8~<)dTL{sWV}^2Ewy`!WGi=PIHoMs5HgY}MMDYT@ZD*gwi@?ug?5F_%P*7si{e*sQu7qH2Bq}I`yPb)WMDjo!0IW$8UQlp2 zQ;68kWU)C!F4HwAanUl1P+BmVURX(gf%}Tl;A~i{A3KS zh{!OZkVinH#bPl^j74$zEVP-Gl@%Iejy5+p1sSG-7>+PVV#*Qd&AOQPL17Al`D~t$ z&E+6weFkmkiiAWY62uXIDU0MSIOhmHWe=VMS`x%Vo1rl1FUhbG#|W+!SL;H^UP!>j`FN#uzIC2D89+ zkn_Pi>vH~(GIXCpEdJ8_JFVF@YD=9zk;;PT2xvlw0@@7WOujZE#?70y_Am$p05EMKcpNQn~ zxgnxpX2_fb(A_*L;D!ptL42ki3+y2x(k?WV4JwU6U{M&p?58BP|f!7LnKcN>cC~&cG#W6Wx@9@D3?AqJFl>h)qVuMZa zP4NN1aIa`@i;KOdMhA%F}KDow0d|;!vkB zMGUM-&i@c*vMM&GryTQmLTYDElR`*P8|R7_`a*fbEb3@mW8+>Uy#6Rb=jxQnQ}4ZX zqj$f%_KqyYvaDQV$nA?Fu+OlqnkHS^x*0s}n&gmtc6pjMY?$^U15g}s;=hNsi37(C z(LE>CJHnOCPCaWxf!M)2zrFE%Wa2BY8uvtedAtX|xP+oavs^J~3@vKX4$N}`b|WO+ zAGQBjODQUu=&EzCPD@EmwS2g9Rl|nCf^LWWkgMuh*itEWMv}|Deo5KSsXeX7$DlR8 z!FfdGraw@+*U9npFY#GGcau5~M=?^<*Q3b}`DaTx*Tk(b`VAI2#psBaRGpWzZ;*Rf zJHP^RoYFK!uoyIM5af~!Sd+_s|8vun4DutUAFr#y7j8@V5Il@vR7KKZA#;h+G_Sr{z;c!Awgzx zi_(s04CdNGJzo1JRYTV{Udv={%anAeCZ2-v!DJGas5!Uqfoeg{taK?&x~|-_7N+x3 zB{x7Hvpn^MOJI5O5339z{fo6_8B)#@(FNgdn+xGO2Rv;LL8;I_*;{vr`*nTW{p#;Z z?nH=fzu*x*xJ!^_?NzziOnkpL- zWqL^zj0lc^j3^4vHOnPJE-Q7270v3Q`a_+UIv@214_~#64X`4>```Xixo1O4tqY>< z^?CEmx}n-NffZ6}gd*)l=`N{}zPPT%GpP;=j|<(YrRJ%CNWA10is72v*=;8N@ZyZIJB%FPHaX%mukDK`b@6Q&{_YU2x)wRo$y6k_XIc;$M zL)?lz!jEyo@C^!ETnlu|81_ceLJxx(EstFVFu$JBW0Gz6L{*sgYlmP{OVuwwb-Jzg z>-VjfOXZO7M(Xp%8V-&*iwGCwNyxHI>V*bb@FT6I?aO$m*39y)#bXR5${tL3ld@2@>zgn%(_A01Qk zIO9rCpd0lT>Gy8gq;NzaD`a$+c_-~UtYrVj3p2GNT!_3%lygEwM8eJQ)}lu@Z_O z4|zFt^-eCnV9?qXnL1MYm>bm(A=^}38M=3WqrbX(RF z^(S>)?wyu}{rx3cYTbH5`BBXpldetEHV5jmU34{h%B1uy9dRwb3RF#qbF$zfEc((K zEl#o)J-Nqnp!l@qDy)${q^kPOnq!B09S%*Gyq2G+s_|?~o7R;!tjm&KdG0$dryax4 z7}01WC^o*5AFH+8sh4~lHSAc?aXTh012`trI|$uea9##QZqf|#Z}Y|W+^M#{xC&ZN z%*_M_8d`FJEhvggRAyNIHdbxR7?iwS#me*LW#S1*VjpK#cHRZ z1f-UkUTaKG00ge>47a1{kCl6w{-y;j@4AXb$d_D*M3X{{r*C!e9UZ literal 0 HcmV?d00001