This commit is contained in:
syuilo 2026-05-28 17:32:45 +09:00
commit 0a6bfce548
4 changed files with 39 additions and 11 deletions

View file

@ -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;
}

View file

@ -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();
},
};
},

View file

@ -39,6 +39,6 @@ export function defineAccessorySchema<const OpSc extends AvatarAccessoryOptionsS
return def;
}
export function defineAccessory<const Schema extends AccessorySchemaDef<any>>(schema: Schema, def: Pick<AccessoryDef<Schema>, 'path' | 'createInstance'>): AccessoryDef<Schema> {
export function defineAccessory<const Schema extends AccessorySchemaDef<any>>(schema: Schema, def: Pick<AvatarAccessoryDef<Schema>, 'path' | 'createInstance'>): AvatarAccessoryDef<Schema> {
return { ...schema, ...def };
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB