mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-13 16:25:44 +02:00
wip
This commit is contained in:
@@ -94,6 +94,16 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkButton danger @click="revert">戻す</MkButton>
|
||||
<MkButton primary @click="save">保存</MkButton>
|
||||
</div>
|
||||
<MkSelect
|
||||
:modelValue="graphicsQuality" :items="[
|
||||
{ label: 'High', value: 'high' },
|
||||
{ label: 'Medium', value: 'medium' },
|
||||
{ label: 'Low', value: 'low' },
|
||||
]" @update:modelValue="v => graphicsQuality = v"
|
||||
>
|
||||
<template #label>Graphics quality</template>
|
||||
</MkSelect>
|
||||
<MkButton danger @click="reload">reload</MkButton>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -130,6 +140,7 @@ function resize() {
|
||||
const isZenMode = ref(false);
|
||||
const isRoomSettingsOpen = ref(false);
|
||||
const isChanged = ref(false);
|
||||
const graphicsQuality = ref<'low' | 'medium' | 'high'>('medium');
|
||||
|
||||
const data = localStorage.getItem('roomData') != null ? JSON.parse(localStorage.getItem('roomData')!) : {
|
||||
heya: {
|
||||
@@ -166,14 +177,14 @@ const data = localStorage.getItem('roomData') != null ? JSON.parse(localStorage.
|
||||
installedObjects: [],
|
||||
};
|
||||
|
||||
console.log(data);
|
||||
|
||||
let latestData = deepClone(data);
|
||||
|
||||
const controller = new RoomController(data);
|
||||
|
||||
onMounted(async () => {
|
||||
controller.init(canvas.value!);
|
||||
controller.init(canvas.value!, {
|
||||
graphicsQuality: graphicsQuality.value,
|
||||
});
|
||||
|
||||
canvas.value!.focus();
|
||||
|
||||
@@ -299,6 +310,12 @@ async function revert() {
|
||||
isChanged.value = false;
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
await controller.reset(null, null, {
|
||||
graphicsQuality: graphicsQuality.value,
|
||||
});
|
||||
}
|
||||
|
||||
function expor() {
|
||||
const dataStr = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(controller.roomState.value));
|
||||
const dlAnchorElem = window.document.createElement('a');
|
||||
|
||||
@@ -13,11 +13,17 @@ import type { RoomState } from './engine.js';
|
||||
import type { ObjectDef, RoomStateObject } from './object.js';
|
||||
import * as sound from '@/utility/sound.js';
|
||||
|
||||
type Options = {
|
||||
workerMode?: boolean;
|
||||
graphicsQuality?: 'low' | 'medium' | 'high';
|
||||
};
|
||||
|
||||
// 抽象化レイヤー
|
||||
export class RoomController {
|
||||
private worker: Worker | null = null;
|
||||
private engine: RoomEngine | null = null;
|
||||
private canvas: HTMLCanvasElement | null = null;
|
||||
private options: Options = {};
|
||||
private isCanvasDragging = false;
|
||||
public isReady = ref(false);
|
||||
public isSitting = ref(false);
|
||||
@@ -44,21 +50,23 @@ export class RoomController {
|
||||
this.onCanvasClick = this.onCanvasClick.bind(this);
|
||||
}
|
||||
|
||||
public async init(canvas: HTMLCanvasElement, workerMode = false) {
|
||||
public async init(canvas: HTMLCanvasElement, options: Options = {}) {
|
||||
this.canvas = canvas;
|
||||
this.canvas.width = canvas.clientWidth;
|
||||
this.canvas.height = canvas.clientHeight;
|
||||
this.options = options;
|
||||
|
||||
if (workerMode) {
|
||||
if (options.workerMode) {
|
||||
const offscreen = canvas.transferControlToOffscreen();
|
||||
this.worker = new RoomWorker();
|
||||
this.worker.postMessage({ type: 'init', canvas: offscreen, roomState: this.roomState.value }, [offscreen]);
|
||||
this.worker.postMessage({ type: 'init', canvas: offscreen, roomState: this.roomState.value, graphicsQuality: options.graphicsQuality }, [offscreen]);
|
||||
this.isReady.value = true;
|
||||
} else {
|
||||
const babylonEngine = new BABYLON.WebGPUEngine(canvas, { doNotHandleContextLost: true });
|
||||
babylonEngine.compatibilityMode = false;
|
||||
await babylonEngine.initAsync();
|
||||
this.engine = new RoomEngine(this.roomState.value, { canvas, engine: babylonEngine });
|
||||
|
||||
this.engine = new RoomEngine(this.roomState.value, { canvas, engine: babylonEngine, graphicsQuality: options.graphicsQuality });
|
||||
this.engine.on('loadingProgress', ({ progress }) => {
|
||||
this.initializeProgress.value = progress;
|
||||
});
|
||||
@@ -163,16 +171,16 @@ export class RoomController {
|
||||
return false;
|
||||
}
|
||||
|
||||
public async reset(roomState: RoomState, canvas?: HTMLCanvasElement, workerMode = false) {
|
||||
public async reset(roomState?: RoomState, canvas?: HTMLCanvasElement, options: Options = {}) {
|
||||
this.destroy();
|
||||
this.roomState.value = roomState;
|
||||
if (roomState != null) this.roomState.value = roomState;
|
||||
this.isReady.value = false;
|
||||
this.isSitting.value = false;
|
||||
this.isEditMode.value = false;
|
||||
this.grabbing.value = null;
|
||||
this.selected.value = null;
|
||||
this.initializeProgress.value = 0;
|
||||
await this.init(canvas ?? this.canvas!, workerMode);
|
||||
await this.init(canvas ?? this.canvas!, options ?? this.options);
|
||||
}
|
||||
|
||||
public pauseRender() {
|
||||
|
||||
@@ -26,7 +26,6 @@ import { deepClone } from '@/utility/clone.js';
|
||||
const BAKE_TRANSFORM = false; // 実験的
|
||||
const SNAPSHOT_RENDERING = true; // 実験的
|
||||
const IGNORE_OBJECTS: string[] = []; // for debug
|
||||
const USE_GLOW = true; // ドローコールが増えて重い
|
||||
const RENDER_OUTDOOR_ENV = false;
|
||||
const IN_WEB_WORKER = typeof window === 'undefined';
|
||||
|
||||
@@ -117,6 +116,7 @@ export type RoomEngineEvents = {
|
||||
};
|
||||
|
||||
export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
||||
private useGlow: boolean;
|
||||
private canvas: HTMLCanvasElement;
|
||||
private engine: BABYLON.WebGPUEngine;
|
||||
public scene: BABYLON.Scene;
|
||||
@@ -218,6 +218,7 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
||||
constructor(roomState: RoomState, options: {
|
||||
canvas: HTMLCanvasElement;
|
||||
engine: BABYLON.WebGPUEngine;
|
||||
graphicsQuality?: 'low' | 'medium' | 'high';
|
||||
}) {
|
||||
super();
|
||||
|
||||
@@ -230,9 +231,13 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
||||
};
|
||||
this.canvas = options.canvas;
|
||||
|
||||
this.fps = options.graphicsQuality === 'low' || options.graphicsQuality === 'medium' ? 30 : null;
|
||||
this.useGlow = options.graphicsQuality !== 'low';
|
||||
|
||||
registerBuiltInLoaders();
|
||||
|
||||
this.engine = options.engine;
|
||||
if (options.graphicsQuality === 'low') this.engine.setHardwareScalingLevel(2);
|
||||
this.scene = new BABYLON.Scene(this.engine);
|
||||
// なんかレンダリングがおかしくなるときがあるのでコメントアウト
|
||||
// オブジェクトを選択し、後ろを向いて別のオブジェクトを選択した後、最初のオブジェクトに振り返ると消えているなど
|
||||
@@ -350,7 +355,7 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
||||
|
||||
this.turnOnRoomLight(true);
|
||||
|
||||
if (USE_GLOW) {
|
||||
if (this.useGlow) {
|
||||
this.gl = new BABYLON.GlowLayer('glow', this.scene, {
|
||||
//mainTextureFixedSize: 512,
|
||||
blurKernelSize: 64,
|
||||
@@ -407,7 +412,7 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
|
||||
|
||||
if (_DEV_) {
|
||||
// snapshot renderingかつglow layerが有効だとなんかクラッシュする
|
||||
if (!(SNAPSHOT_RENDERING && USE_GLOW)) {
|
||||
if (!(SNAPSHOT_RENDERING && this.useGlow)) {
|
||||
const axes = new AxesViewer(this.scene, 30);
|
||||
axes.xAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||
axes.yAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||
|
||||
Reference in New Issue
Block a user