1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-15 16:15:51 +02:00
This commit is contained in:
syuilo
2026-04-15 18:10:42 +09:00
parent 7eb8723082
commit 6275196101
3 changed files with 75 additions and 32 deletions

View File

@@ -6,7 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div :class="$style.root" class="_pageScrollable">
<div :class="[$style.screen, { [$style.zen]: isZenMode }]">
<canvas ref="canvas" :class="$style.canvas" tabindex="-1"></canvas>
<canvas ref="canvas" :class="$style.canvas" tabindex="-1" :style="{ visibility: controller.isReady.value ? 'visible' : 'hidden' }"></canvas>
<div v-if="!controller.isReady.value" :class="$style.loading">
<div :class="$style.progressBar">
<div :class="$style.progressBarValue" :style="{ width: `${controller.initializeProgress.value * 100}%` }"></div>
</div>
</div>
<template v-if="!isZenMode">
<div v-if="controller.isReady.value" class="_buttonsCenter" :class="$style.overlayControls">
@@ -371,4 +377,25 @@ definePage(() => ({
box-sizing: border-box;
width: 300px;
}
.loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.progressBar {
width: 100%;
height: 4px;
}
.progressBarValue {
height: 100%;
background: linear-gradient(90deg, var(--MI_THEME-buttonGradateA), var(--MI_THEME-buttonGradateB));
transition: all 0.5s cubic-bezier(0,.5,.5,1);
}
</style>

View File

@@ -27,6 +27,7 @@ export class RoomController {
objectDef: ObjectDef;
} | null>(null);
public roomState: ShallowRef<RoomState>;
public initializeProgress = ref(0);
constructor(roomState: RoomState) {
this.roomState = shallowRef(roomState);
@@ -45,35 +46,38 @@ export class RoomController {
} else {
const babylonEngine = new BABYLON.WebGPUEngine(canvas);
babylonEngine.compatibilityMode = false;
babylonEngine.initAsync().then(() => {
this.engine = new RoomEngine(this.roomState.value, { canvas, engine: babylonEngine });
this.engine.init();
this.isReady.value = true;
await babylonEngine.initAsync();
this.engine = new RoomEngine(this.roomState.value, { canvas, engine: babylonEngine });
this.engine.on('loadingProgress', ({ progress }) => {
this.initializeProgress.value = progress;
});
await this.engine.init();
this.initializeProgress.value = 1;
this.isReady.value = true;
this.engine.on('changeGrabbingState', ({ grabbing }) => {
this.grabbing.value = grabbing;
});
this.engine.on('changeGrabbingState', ({ grabbing }) => {
this.grabbing.value = grabbing;
});
this.engine.on('changeEditMode', ({ isEditMode }) => {
this.isEditMode.value = isEditMode;
});
this.engine.on('changeEditMode', ({ isEditMode }) => {
this.isEditMode.value = isEditMode;
});
this.engine.on('changeGridSnapping', ({ gridSnapping }) => {
this.gridSnapping.value = gridSnapping;
});
this.engine.on('changeGridSnapping', ({ gridSnapping }) => {
this.gridSnapping.value = gridSnapping;
});
this.engine.on('changeSelectedState', ({ selected }) => {
this.selected.value = selected;
});
this.engine.on('changeSelectedState', ({ selected }) => {
this.selected.value = selected;
});
this.engine.on('changeRoomState', ({ roomState }) => {
this.roomState.value = roomState;
triggerRef(this.selected);
});
this.engine.on('changeRoomState', ({ roomState }) => {
this.roomState.value = roomState;
triggerRef(this.selected);
});
this.engine.on('playSfxUrl', ({ url, options }) => {
sound.playUrl(url, options);
});
this.engine.on('playSfxUrl', ({ url, options }) => {
sound.playUrl(url, options);
});
}

View File

@@ -408,6 +408,7 @@ export type RoomEngineEvents = {
playbackRate: number;
};
}) => void;
'loadingProgress': (ctx: { progress: number }) => void;
};
export class RoomEngine extends EventEmitter<RoomEngineEvents> {
@@ -733,15 +734,24 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
public async init() {
await this.loadRoomModel();
//await this.loadEnvModel();
await Promise.all(this.roomState.installedObjects.filter(o => !IGNORE_OBJECTS.includes(o.type) && (!SNAPSHOT_RENDERING || !SNAPSHOT_RENDERING_NON_SUPPORTED_OBJECTS.includes(o.type))).map(o => this.loadObject({
const objects = this.roomState.installedObjects.filter(o => !IGNORE_OBJECTS.includes(o.type) && (!SNAPSHOT_RENDERING || !SNAPSHOT_RENDERING_NON_SUPPORTED_OBJECTS.includes(o.type)));
let loadedCount = 0;
await Promise.all(objects.map(o => this.loadObject({
id: o.id,
type: o.type,
position: new BABYLON.Vector3(...o.position),
rotation: new BABYLON.Vector3(o.rotation[0], o.rotation[1], o.rotation[2]),
options: o.options,
}).then(() => {
loadedCount++;
this.emit('loadingProgress', { progress: loadedCount / objects.length });
})));
//const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: cm(1) }, this.scene);
if (SNAPSHOT_RENDERING) {
this.sr.enableSnapshotRendering();
}
if (this.fps == null) {
this.engine.runRenderLoop(() => {
@@ -768,12 +778,6 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
window.requestAnimationFrame(renderLoop);
}
if (SNAPSHOT_RENDERING) {
window.setTimeout(() => {
this.sr.enableSnapshotRendering();
}, 3000);
}
this.domEvents.on('keydown', (ev) => {
if (ev.code === 'KeyE') {
if (this.isEditMode) {
@@ -1765,12 +1769,20 @@ export class RoomEngine extends EventEmitter<RoomEngineEvents> {
for (const entity of this.objectEntities.values()) {
entity.instance.resetTemporaryState?.();
}
if (SNAPSHOT_RENDERING) {
this.sr.disableSnapshotRendering();
}
}
public async exitEditMode() {
this.isEditMode = false;
await this.bake();
if (SNAPSHOT_RENDERING) {
this.sr.enableSnapshotRendering();
}
}
public async bake() {