wip
@@ -20,6 +20,7 @@ export abstract class EngineBase<EVs extends EngineBaseEvents> extends EventEmit
|
||||
|
||||
protected engine: BABYLON.WebGPUEngine;
|
||||
public scene: BABYLON.Scene;
|
||||
abstract sr: BABYLON.SnapshotRenderingHelper;
|
||||
protected fps: number | null = null;
|
||||
protected disposed = false;
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as BABYLON from '@babylonjs/core/pure.js';
|
||||
import { cm, WORLD_SCALE } from 'misskey-world/src/utility.js';
|
||||
import { randomRange, Timer } from './utility.js';
|
||||
import type { EngineBase } from './EngineBase.js';
|
||||
|
||||
export class Firework {
|
||||
private engine: EngineBase<any>;
|
||||
private timer: Timer = new Timer();
|
||||
|
||||
constructor(engine: EngineBase<any>) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
public launch(options: {
|
||||
position: [number, number, number];
|
||||
}) {
|
||||
this.engine.sr.disableSnapshotRendering();
|
||||
|
||||
const texture = new BABYLON.Texture(`/client-assets/world/other/firework/flare-${Math.round(randomRange(1, 8))}.png`, this.engine.scene);
|
||||
|
||||
//const emitter = new BABYLON.TransformNode('emitter', this.engine.scene);
|
||||
const emitter = BABYLON.MeshBuilder.CreateBox('emitter', { size: cm(10) }, this.engine.scene);
|
||||
emitter.position = new BABYLON.Vector3(options.position[0], options.position[1], options.position[2]);
|
||||
const ps = new BABYLON.ParticleSystem('', 128, this.engine.scene);
|
||||
ps.particleTexture = texture;
|
||||
ps.emitter = emitter;
|
||||
ps.minEmitPower = cm(100);
|
||||
ps.maxEmitPower = cm(500);
|
||||
ps.minLifeTime = 0.5;
|
||||
ps.maxLifeTime = 1;
|
||||
ps.minSize = cm(3);
|
||||
ps.maxSize = cm(30);
|
||||
//ps.direction1 = new BABYLON.Vector3(0, 1, 0);
|
||||
//ps.direction2 = new BABYLON.Vector3(0, 1, 0);
|
||||
ps.emitRate = 20;
|
||||
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.start();
|
||||
|
||||
this.engine.sr.fixParticleSystem(ps);
|
||||
|
||||
const launchAnim = new BABYLON.Animation(
|
||||
'',
|
||||
'position',
|
||||
60,
|
||||
BABYLON.Animation.ANIMATIONTYPE_VECTOR3,
|
||||
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT,
|
||||
);
|
||||
launchAnim.setKeys([
|
||||
{ frame: 0, value: new BABYLON.Vector3(options.position[0], options.position[1], options.position[2]) },
|
||||
{ frame: 60, value: new BABYLON.Vector3(options.position[0], options.position[1] + cm(randomRange(1000, 3000)), options.position[2]) },
|
||||
]);
|
||||
|
||||
emitter.animations.push(launchAnim);
|
||||
const animating = Promise.withResolvers<void>();
|
||||
const animationObserver = this.engine.scene.onAfterAnimationsObservable.add(() => {
|
||||
});
|
||||
this.engine.scene.beginAnimation(emitter, 0, 60, false, 1, () => { animating.resolve(); });
|
||||
animating.promise.then(() => {
|
||||
this.engine.scene.onAfterAnimationsObservable.remove(animationObserver);
|
||||
|
||||
ps.stop();
|
||||
|
||||
this.timer.setTimeout(() => {
|
||||
ps.dispose();
|
||||
emitter.dispose();
|
||||
}, 1000);
|
||||
|
||||
this.explode({
|
||||
position: [emitter.position.x, emitter.position.y, emitter.position.z],
|
||||
texture,
|
||||
});
|
||||
});
|
||||
|
||||
//this.engine.sr.enableSnapshotRendering();
|
||||
}
|
||||
|
||||
public explode(options: {
|
||||
position: [number, number, number];
|
||||
texture: BABYLON.Texture;
|
||||
}) {
|
||||
const ps = new BABYLON.ParticleSystem('', 128, this.engine.scene);
|
||||
ps.particleTexture = options.texture;
|
||||
ps.emitter = new BABYLON.Vector3(options.position[0], options.position[1], options.position[2]);
|
||||
ps.minEmitPower = cm(2000);
|
||||
ps.maxEmitPower = cm(4000);
|
||||
ps.minLifeTime = 0.7;
|
||||
ps.maxLifeTime = 1;
|
||||
ps.addDragGradient(0, 0.1);
|
||||
ps.addDragGradient(1, 0.8);
|
||||
ps.gravity = new BABYLON.Vector3(0, -30, 0).scale(WORLD_SCALE);
|
||||
ps.minSize = cm(20);
|
||||
ps.maxSize = cm(40);
|
||||
const sphereEmitter = ps.createSphereEmitter(cm(1));
|
||||
//ps.direction1 = new BABYLON.Vector3(0, 1, 0);
|
||||
//ps.direction2 = new BABYLON.Vector3(0, 1, 0);
|
||||
ps.manualEmitCount = 100;
|
||||
ps.blendMode = BABYLON.ParticleSystem.BLENDMODE_ADD;
|
||||
ps.color1 = new BABYLON.Color4(1, 1, 1, 1);
|
||||
ps.color2 = new BABYLON.Color4(1, 1, 1, 1);
|
||||
ps.colorDead = new BABYLON.Color4(1, 1, 1, 0);
|
||||
ps.start();
|
||||
|
||||
this.engine.sr.fixParticleSystem(ps);
|
||||
|
||||
this.timer.setTimeout(() => {
|
||||
ps.dispose();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this.timer.dispose();
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import Hls from 'hls.js';
|
||||
import { findMaterial, GRAPHICS_QUALITY, Timer } from '../utility.js';
|
||||
import { WorldEnvManager } from '../env.js';
|
||||
import { RecyvlingTextGrid, createPlaneUvMapper, randomRange } from '../utility.js';
|
||||
import { Firework } from '../Firework.js';
|
||||
import type { WorldEngine } from '../engine.js';
|
||||
|
||||
export class LobbyEnvManager extends WorldEnvManager {
|
||||
@@ -447,31 +448,37 @@ export class LobbyEnvManager extends WorldEnvManager {
|
||||
this.engine.sr.updateMesh([...hourHands, ...minuteHands], false);
|
||||
}, 1000);
|
||||
|
||||
const emitter = new BABYLON.TransformNode('emitter', this.engine.scene);
|
||||
emitter.position = new BABYLON.Vector3(0, cm(-1000), 0);
|
||||
const ps = new BABYLON.ParticleSystem('', 128, this.engine.scene);
|
||||
ps.particleTexture = new BABYLON.Texture('/client-assets/world/envs/lobby/bubble.png');
|
||||
ps.emitter = emitter;
|
||||
ps.isLocal = true;
|
||||
ps.minEmitBox = new BABYLON.Vector3(cm(-1000), 0, cm(-1000));
|
||||
ps.maxEmitBox = new BABYLON.Vector3(cm(1000), 0, cm(1000));
|
||||
ps.minEmitPower = cm(100);
|
||||
ps.maxEmitPower = cm(500);
|
||||
ps.minLifeTime = 30;
|
||||
ps.maxLifeTime = 30;
|
||||
ps.minSize = cm(30);
|
||||
ps.maxSize = cm(300);
|
||||
ps.direction1 = new BABYLON.Vector3(0, 1, 0);
|
||||
ps.direction2 = new BABYLON.Vector3(0, 1, 0);
|
||||
ps.emitRate = 1.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();
|
||||
//const emitter = new BABYLON.TransformNode('emitter', this.engine.scene);
|
||||
//emitter.position = new BABYLON.Vector3(0, cm(-1000), 0);
|
||||
//const ps = new BABYLON.ParticleSystem('', 128, this.engine.scene);
|
||||
//ps.particleTexture = new BABYLON.Texture('/client-assets/world/envs/lobby/bubble.png');
|
||||
//ps.emitter = emitter;
|
||||
//ps.isLocal = true;
|
||||
//ps.minEmitBox = new BABYLON.Vector3(cm(-1000), 0, cm(-1000));
|
||||
//ps.maxEmitBox = new BABYLON.Vector3(cm(1000), 0, cm(1000));
|
||||
//ps.minEmitPower = cm(100);
|
||||
//ps.maxEmitPower = cm(500);
|
||||
//ps.minLifeTime = 30;
|
||||
//ps.maxLifeTime = 30;
|
||||
//ps.minSize = cm(30);
|
||||
//ps.maxSize = cm(300);
|
||||
//ps.direction1 = new BABYLON.Vector3(0, 1, 0);
|
||||
//ps.direction2 = new BABYLON.Vector3(0, 1, 0);
|
||||
//ps.emitRate = 1.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();
|
||||
//this.engine.sr.fixParticleSystem(ps);
|
||||
|
||||
this.engine.sr.fixParticleSystem(ps);
|
||||
this.timer.setInterval(() => {
|
||||
const firework = new Firework(this.engine);
|
||||
firework.launch({
|
||||
position: [randomRange(cm(-2000), cm(2000)), cm(randomRange(1000, 3000)), randomRange(cm(-2000), cm(2000))],
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
this.registerMeshes(this.meshes);
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |