mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-18 20:05:26 +02:00
wip
This commit is contained in:
@@ -269,6 +269,7 @@ const roomControllerOptions = computed<RoomControllerOptions>(() => ({
|
|||||||
fps: fps.value,
|
fps: fps.value,
|
||||||
resolution: resolution.value,
|
resolution: resolution.value,
|
||||||
useVirtualJoystick,
|
useVirtualJoystick,
|
||||||
|
workerMode: false,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const controller = new RoomController(data, roomControllerOptions.value);
|
const controller = new RoomController(data, roomControllerOptions.value);
|
||||||
|
|||||||
@@ -62,8 +62,23 @@ export class RoomController {
|
|||||||
if (this.options.workerMode) {
|
if (this.options.workerMode) {
|
||||||
const offscreen = canvas.transferControlToOffscreen();
|
const offscreen = canvas.transferControlToOffscreen();
|
||||||
this.worker = new RoomWorker();
|
this.worker = new RoomWorker();
|
||||||
this.worker.postMessage({ type: 'init', canvas: offscreen, roomState: this.roomState.value, ...this.options }, [offscreen]);
|
this.worker.postMessage({ type: 'init', canvas: offscreen, roomState: this.roomState.value, options: this.options }, [offscreen]);
|
||||||
this.isReady.value = true;
|
this.worker.onmessage = (event) => {
|
||||||
|
switch (event.data?.type) {
|
||||||
|
case 'progress': {
|
||||||
|
this.initializeProgress.value = event.data.progress;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'inited': {
|
||||||
|
this.initializeProgress.value = 1;
|
||||||
|
this.isReady.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
console.warn('Unrecognized message from worker:', event.data?.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
const babylonEngine = new BABYLON.WebGPUEngine(canvas, { doNotHandleContextLost: true });
|
const babylonEngine = new BABYLON.WebGPUEngine(canvas, { doNotHandleContextLost: true });
|
||||||
babylonEngine.compatibilityMode = false;
|
babylonEngine.compatibilityMode = false;
|
||||||
@@ -104,6 +119,14 @@ export class RoomController {
|
|||||||
this.engine.on('playSfxUrl', ({ url, options }) => {
|
this.engine.on('playSfxUrl', ({ url, options }) => {
|
||||||
sound.playUrl(url, options);
|
sound.playUrl(url, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (_DEV_) {
|
||||||
|
(window as any).showBabylonInspector = () => {
|
||||||
|
import('@babylonjs/inspector').then(({ ShowInspector }) => {
|
||||||
|
ShowInspector(this.engine.scene);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.canvas.addEventListener('keydown', this.onCanvasKeydown);
|
this.canvas.addEventListener('keydown', this.onCanvasKeydown);
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
// TODO: テクスチャ置き換え時、元のテクスチャをちゃんとdispose
|
// TODO: テクスチャ置き換え時、元のテクスチャをちゃんとdispose
|
||||||
|
|
||||||
import * as BABYLON from '@babylonjs/core';
|
import * as BABYLON from '@babylonjs/core';
|
||||||
import { AxesViewer } from '@babylonjs/core/Debug/axesViewer';
|
|
||||||
import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic';
|
import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic';
|
||||||
import { BoundingBoxRenderer } from '@babylonjs/core/Rendering/boundingBoxRenderer';
|
|
||||||
import { GridMaterial } from '@babylonjs/materials';
|
import { GridMaterial } from '@babylonjs/materials';
|
||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
import { TIME_MAP, scaleMorph, camelToKebab, cm, WORLD_SCALE, getMeshesBoundingBox, Timer, getYRotationDirection, FreeCameraTouchVirtualJoystickInput } from '../utility.js';
|
import { TIME_MAP, scaleMorph, camelToKebab, cm, WORLD_SCALE, getMeshesBoundingBox, Timer, getYRotationDirection, FreeCameraTouchVirtualJoystickInput } from '../utility.js';
|
||||||
@@ -437,18 +435,13 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
// snapshot renderingかつglow layerが有効だとなんかクラッシュする
|
// snapshot renderingかつglow layerが有効だとなんかクラッシュする
|
||||||
if (!(SNAPSHOT_RENDERING && this.useGlow)) {
|
if (!(SNAPSHOT_RENDERING && this.useGlow)) {
|
||||||
const axes = new AxesViewer(this.scene, 30);
|
import('@babylonjs/core/Debug/axesViewer').then(m => {
|
||||||
axes.xAxis.position = new BABYLON.Vector3(0, 30, 0);
|
const { AxesViewer } = m;
|
||||||
axes.yAxis.position = new BABYLON.Vector3(0, 30, 0);
|
const axes = new AxesViewer(this.scene, 30);
|
||||||
axes.zAxis.position = new BABYLON.Vector3(0, 30, 0);
|
axes.xAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
}
|
axes.yAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
|
axes.zAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
if (!IN_WEB_WORKER) {
|
});
|
||||||
(window as any).showBabylonInspector = () => {
|
|
||||||
import('@babylonjs/inspector').then(({ ShowInspector }) => {
|
|
||||||
ShowInspector(this.scene);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -588,7 +581,8 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
const renderLoop = (timeStamp: number) => {
|
const renderLoop = (timeStamp: number) => {
|
||||||
if (this.disposed) return;
|
if (this.disposed) return;
|
||||||
|
|
||||||
this.currentRafId = window.requestAnimationFrame(renderLoop);
|
// workerで実行される可能性がある
|
||||||
|
this.currentRafId = requestAnimationFrame(renderLoop);
|
||||||
|
|
||||||
const delta = timeStamp - then;
|
const delta = timeStamp - then;
|
||||||
if (delta <= interval) return;
|
if (delta <= interval) return;
|
||||||
@@ -599,14 +593,16 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
this.engine.endFrame();
|
this.engine.endFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.currentRafId = window.requestAnimationFrame(renderLoop);
|
// workerで実行される可能性がある
|
||||||
|
this.currentRafId = requestAnimationFrame(renderLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public pauseRender() {
|
public pauseRender() {
|
||||||
this.engine.stopRenderLoop();
|
this.engine.stopRenderLoop();
|
||||||
if (this.currentRafId != null) {
|
if (this.currentRafId != null) {
|
||||||
window.cancelAnimationFrame(this.currentRafId);
|
// workerで実行される可能性がある
|
||||||
|
cancelAnimationFrame(this.currentRafId);
|
||||||
this.currentRafId = null;
|
this.currentRafId = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1638,7 +1634,9 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
this.scene.customRenderTargets.push(reflectionProbe.cubeTexture);
|
this.scene.customRenderTargets.push(reflectionProbe.cubeTexture);
|
||||||
reflectionProbe.cubeTexture.render();
|
reflectionProbe.cubeTexture.render();
|
||||||
|
|
||||||
await new Promise(res => window.setTimeout(res, 2000));
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
await new Promise(res => setTimeout(res, 2000));
|
||||||
|
|
||||||
const tex = reflectionProbe.cubeTexture;
|
const tex = reflectionProbe.cubeTexture;
|
||||||
reflectionProbe.renderList = [];
|
reflectionProbe.renderList = [];
|
||||||
@@ -1731,6 +1729,8 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
// ↑追記: engine.resizeした後に一瞬待つことで回避できることが判明
|
// ↑追記: engine.resizeした後に一瞬待つことで回避できることが判明
|
||||||
if (SNAPSHOT_RENDERING) this.sr.disableSnapshotRendering();
|
if (SNAPSHOT_RENDERING) this.sr.disableSnapshotRendering();
|
||||||
this.engine.resize();
|
this.engine.resize();
|
||||||
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (SNAPSHOT_RENDERING) this.sr.enableSnapshotRendering();
|
if (SNAPSHOT_RENDERING) this.sr.enableSnapshotRendering();
|
||||||
}, 1);
|
}, 1);
|
||||||
@@ -1738,7 +1738,8 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
|||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
if (this.currentRafId != null) {
|
if (this.currentRafId != null) {
|
||||||
window.cancelAnimationFrame(this.currentRafId);
|
// workerで実行される可能性がある
|
||||||
|
cancelAnimationFrame(this.currentRafId);
|
||||||
this.currentRafId = null;
|
this.currentRafId = null;
|
||||||
}
|
}
|
||||||
this.timer.dispose();
|
this.timer.dispose();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import * as BABYLON from '@babylonjs/core';
|
import * as BABYLON from '@babylonjs/core';
|
||||||
import { applyMorphTargetsToMesh, cm, getPlaneUvIndexes, Timer } from '../utility.js';
|
import { applyMorphTargetsToMesh, cm, getPlaneUvIndexes, Timer } from '../utility.js';
|
||||||
import type { RoomEngine } from './engine.js';
|
|
||||||
|
|
||||||
export const SYSTEM_MESH_NAMES = ['__TOP__', '__SIDE__', '__PICK__', '__COLLISION__'];
|
export const SYSTEM_MESH_NAMES = ['__TOP__', '__SIDE__', '__PICK__', '__COLLISION__'];
|
||||||
export const SYSTEM_HEYA_MESH_NAMES = ['__ROOM_WALL__', '__ROOM_SIDE__', '__ROOM_FLOOR__', '__ROOM_CEILING__', '__ROOM_TOP__', '__ROOM_BOTTOM__'];
|
export const SYSTEM_HEYA_MESH_NAMES = ['__ROOM_WALL__', '__ROOM_SIDE__', '__ROOM_FLOOR__', '__ROOM_CEILING__', '__ROOM_TOP__', '__ROOM_BOTTOM__'];
|
||||||
|
|||||||
@@ -21,8 +21,15 @@ onmessage = async (event) => {
|
|||||||
babylonEngine.compatibilityMode = false;
|
babylonEngine.compatibilityMode = false;
|
||||||
babylonEngine.enableOfflineSupport = false;
|
babylonEngine.enableOfflineSupport = false;
|
||||||
await babylonEngine.initAsync();
|
await babylonEngine.initAsync();
|
||||||
engine = new RoomEngine(roomState, { canvas, engine: babylonEngine });
|
if (event.data.options.resolution === 2) babylonEngine.setHardwareScalingLevel(0.5);
|
||||||
|
if (event.data.options.resolution === 0.5) babylonEngine.setHardwareScalingLevel(2);
|
||||||
|
|
||||||
|
engine = new RoomEngine(roomState, { canvas, engine: babylonEngine, ...event.data.options });
|
||||||
|
engine.on('loadingProgress', ({ progress }) => {
|
||||||
|
self.postMessage({ type: 'progress', progress });
|
||||||
|
});
|
||||||
await engine.init();
|
await engine.init();
|
||||||
|
self.postMessage({ type: 'inited' });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'resize': {
|
case 'resize': {
|
||||||
|
|||||||
@@ -544,6 +544,8 @@ export class RecyvlingTextGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function sleep(ms: number) {
|
export function sleep(ms: number) {
|
||||||
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +554,9 @@ export class Timer {
|
|||||||
private intervalIds: number[] = [];
|
private intervalIds: number[] = [];
|
||||||
|
|
||||||
public setTimeout(callback: () => void, ms: number) {
|
public setTimeout(callback: () => void, ms: number) {
|
||||||
const id = window.setTimeout(() => {
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
const id = setTimeout(() => {
|
||||||
this.timeoutIds = this.timeoutIds.filter(i => i !== id);
|
this.timeoutIds = this.timeoutIds.filter(i => i !== id);
|
||||||
callback();
|
callback();
|
||||||
}, ms);
|
}, ms);
|
||||||
@@ -560,18 +564,24 @@ export class Timer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setInterval(callback: () => void, ms: number) {
|
public setInterval(callback: () => void, ms: number) {
|
||||||
const id = window.setInterval(callback, ms);
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
const id = setInterval(callback, ms);
|
||||||
this.intervalIds.push(id);
|
this.intervalIds.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose() {
|
public dispose() {
|
||||||
for (const id of this.timeoutIds) {
|
for (const id of this.timeoutIds) {
|
||||||
window.clearTimeout(id);
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
clearTimeout(id);
|
||||||
}
|
}
|
||||||
this.timeoutIds = [];
|
this.timeoutIds = [];
|
||||||
|
|
||||||
for (const id of this.intervalIds) {
|
for (const id of this.intervalIds) {
|
||||||
window.clearInterval(id);
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
clearInterval(id);
|
||||||
}
|
}
|
||||||
this.intervalIds = [];
|
this.intervalIds = [];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user