This commit is contained in:
syuilo 2026-06-12 13:39:41 +09:00
commit cf2139d515
7 changed files with 100 additions and 11 deletions

View file

@ -3597,6 +3597,8 @@ _miWorld:
sit: "座る"
lyingDown: "寝そべる"
standUp: "立ち上がる"
showUsernameOnAvatar: "アバターにユーザー名を表示"
show2dAvatarOnAvatar: "アバターにユーザーアイコンを表示"
_avatars:
_default:

View file

@ -187,8 +187,9 @@ export class RoomEngine extends EngineBase<{
}
private playerProfiles: Record<string, PlayerProfile> = {};
private playerStates: Record<string, PlayerState> = {};
private playerContainers: PlayerContainer[] = [];
private showUsernameOnAvatar: boolean;
private show2dAvatarOnAvatar: boolean;
private inited = false;
@ -199,6 +200,8 @@ export class RoomEngine extends EngineBase<{
antialias: boolean;
fov: number;
useVirtualJoystick?: boolean;
showUsernameOnAvatar: boolean;
show2dAvatarOnAvatar: boolean;
}) {
super({
engine: options.engine,
@ -216,6 +219,8 @@ export class RoomEngine extends EngineBase<{
this.graphicsQuality = options.graphicsQuality;
this.useGlow = this.graphicsQuality >= GRAPHICS_QUALITY.MEDIUM;
this.fov = options.fov;
this.showUsernameOnAvatar = options.showUsernameOnAvatar;
this.show2dAvatarOnAvatar = options.show2dAvatarOnAvatar;
this.time = TIME_MAP[new Date().getHours() as keyof typeof TIME_MAP];
registerBuiltInLoaders();
@ -1504,8 +1509,8 @@ export class RoomEngine extends EngineBase<{
state: states[k],
scene: this.scene,
sr: this.sr,
showUsername: true,
show2dAvatar: true,
showUsername: this.showUsernameOnAvatar,
show2dAvatar: this.show2dAvatarOnAvatar,
});
// TODO: loadFunitureのものとある程度共通化
p.registerMeshes = (meshes) => {
@ -1568,14 +1573,25 @@ export class RoomEngine extends EngineBase<{
}
public clearPlayers() {
this.sr.disableSnapshotRendering();
for (const playerContainer of this.playerContainers) {
this.sr.disableSnapshotRendering();
playerContainer.destroy();
this.sr.enableSnapshotRendering();
}
this.sr.enableSnapshotRendering();
this.playerContainers = [];
}
public updateAvatarDisplayOptions(options: { showUsername: boolean; show2dAvatar: boolean }) {
this.showUsernameOnAvatar = options.showUsername;
this.show2dAvatarOnAvatar = options.show2dAvatar;
this.sr.disableSnapshotRendering();
for (const playerContainer of this.playerContainers) {
playerContainer.updateUserInfoDisplayOptions(options);
}
this.sr.enableSnapshotRendering();
}
public resize() {
// 一旦snapshot renderingを無効にしておかないとエラーが出る
// ~~...が、一旦無効にしたらしたで複数のマテリアルがそれぞれ入れ替わる(?)という謎の現象が発生するためコメントアウトしとく(エラー出てもレンダリングが止まったりするわけでもないし)~~

View file

@ -11,7 +11,19 @@ import type { RoomState, RoomAttachments } from 'misskey-world/src/room/type.js'
registerBabylonRuntime();
export async function createRoomEngine(params: {
roomState: RoomState; roomAttachments: RoomAttachments; canvas: HTMLCanvasElement; options: { antialias: boolean; resolution: number; fov: number; graphicsQuality: number; fps: number | null; useVirtualJoystick?: boolean; };
roomState: RoomState;
roomAttachments: RoomAttachments;
canvas: HTMLCanvasElement;
options: {
antialias: boolean;
resolution: number;
fov: number;
graphicsQuality: number;
fps: number | null;
useVirtualJoystick?: boolean;
showUsernameOnAvatar: boolean;
show2dAvatarOnAvatar: boolean;
};
}) {
const babylonEngine = new BABYLON.WebGPUEngine(params.canvas, { doNotHandleContextLost: true, powerPreference: 'high-performance', antialias: params.options.antialias });
babylonEngine.compatibilityMode = false;

View file

@ -240,6 +240,8 @@ const resolutionAutoValue = computed<number>(() => deviceKind !== 'desktop' ? 0.
const resolution = computed<number>(() => resolutionRaw.value ?? resolutionAutoValue.value);
const antialias = prefer.model('world.antialias');
const showUsernameOnAvatar = prefer.model('world.showUsernameOnAvatar');
const show2dAvatarOnAvatar = prefer.model('world.show2dAvatarOnAvatar');
const useVirtualJoystick = isTouchUsing && (deviceKind === 'smartphone' || deviceKind === 'tablet');
//const useVirtualJoystick = true;
@ -329,6 +331,8 @@ const roomControllerOptions = computed<RoomControllerOptions>(() => ({
useVirtualJoystick,
fov: prefer.s['world.fov'],
workerMode: prefer.s['world.separateRenderingThread'],
showUsernameOnAvatar: showUsernameOnAvatar.value,
show2dAvatarOnAvatar: show2dAvatarOnAvatar.value,
}));
const controller = markRaw(new RoomController(deepClone(initialRoomState), roomControllerOptions.value));
@ -362,6 +366,13 @@ watch([graphicsQuality, fps, resolution, antialias], () => {
refresh();
});
watch([showUsernameOnAvatar, show2dAvatarOnAvatar], () => {
controller.updateAvatarDisplayOptions({
showUsername: showUsernameOnAvatar.value,
show2dAvatar: show2dAvatarOnAvatar.value,
});
});
controller.addListener('playerPointed', ({ playerId }) => {
pointedPlayerInfo.value = multiplayer.playerProfiles[playerId] ?? null;
isPlayerInfoOpen.value = true;
@ -650,6 +661,7 @@ function showCharacterMenu(ev: PointerEvent) {
function showOnlineMenu(ev: PointerEvent) {
os.popupMenu([{
text: multiplayer.isOnline.value ? i18n.ts._miWorld.disconnectToOnline : i18n.ts._miWorld.connectToOnline,
icon: multiplayer.isOnline.value ? 'ti ti-world-off' : 'ti ti-world',
danger: multiplayer.isOnline.value,
action: () => {
if (multiplayer.isOnline.value) {
@ -658,6 +670,21 @@ function showOnlineMenu(ev: PointerEvent) {
enterOnline();
}
},
}, {
type: 'divider',
}, {
type: 'parent',
text: i18n.ts.settings,
icon: 'ti ti-settings',
children: [{
type: 'switch',
text: i18n.ts._miWorld.showUsernameOnAvatar,
ref: showUsernameOnAvatar,
}, {
type: 'switch',
text: i18n.ts._miWorld.show2dAvatarOnAvatar,
ref: show2dAvatarOnAvatar,
}],
}], ev.currentTarget ?? ev.target);
}

View file

@ -754,11 +754,18 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps_m">
<div class="_gaps_s">
<SearchMarker :keywords="['rendering', 'thread']">
<MkPreferenceContainer k="world.separateRenderingThread">
<MkSwitch v-model="worldSeparateRenderingThread">
<template #label><SearchLabel>{{ i18n.ts._miWorld.separateRenderingThread }}</SearchLabel></template>
<template #caption>{{ i18n.ts._miWorld.separateRenderingThread_description }}</template>
<SearchMarker :keywords="['username']">
<MkPreferenceContainer k="world.showUsernameOnAvatar">
<MkSwitch v-model="worldShowUsernameOnAvatar">
<template #label><SearchLabel>{{ i18n.ts._miWorld.showUsernameOnAvatar }}</SearchLabel></template>
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
<SearchMarker :keywords="['avatar', 'icon']">
<MkPreferenceContainer k="world.show2dAvatarOnAvatar">
<MkSwitch v-model="worldShow2dAvatarOnAvatar">
<template #label><SearchLabel>{{ i18n.ts._miWorld.show2dAvatarOnAvatar }}</SearchLabel></template>
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
@ -839,6 +846,15 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
<SearchMarker :keywords="['rendering', 'thread']">
<MkPreferenceContainer k="world.separateRenderingThread">
<MkSwitch v-model="worldSeparateRenderingThread">
<template #label><SearchLabel>{{ i18n.ts._miWorld.separateRenderingThread }}</SearchLabel></template>
<template #caption>{{ i18n.ts._miWorld.separateRenderingThread_description }}</template>
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
</div>
</MkFolder>
</SearchMarker>
@ -1060,6 +1076,8 @@ const worldFps = prefer.model('world.fps');
const worldResolution = prefer.model('world.resolution');
const worldAntialias = prefer.model('world.antialias');
const worldFov = prefer.model('world.fov');
const worldShowUsernameOnAvatar = prefer.model('world.showUsernameOnAvatar');
const worldShow2dAvatarOnAvatar = prefer.model('world.show2dAvatarOnAvatar');
const fontSize = ref(miLocalStorage.getItem('fontSize') as '1' | '2' | '3' | null);
const useSystemFont = ref(miLocalStorage.getItem('useSystemFont') != null);

View file

@ -23,6 +23,8 @@ export type RoomControllerOptions = {
antialias: boolean;
fov: number;
useVirtualJoystick?: boolean;
showUsernameOnAvatar: boolean;
show2dAvatarOnAvatar: boolean;
};
// 抽象化レイヤー
@ -245,4 +247,8 @@ export class RoomController extends EngineControllerBase<RoomEngine, {
public clearPlayers() {
this.call('clearPlayers');
}
public updateAvatarDisplayOptions(options: { showUsername: boolean; show2dAvatar: boolean }) {
this.call('updateAvatarDisplayOptions', [options]);
}
}

View file

@ -13427,6 +13427,14 @@ export interface Locale extends ILocale {
*
*/
"standUp": string;
/**
*
*/
"showUsernameOnAvatar": string;
/**
*
*/
"show2dAvatarOnAvatar": string;
"_avatars": {
"_default": {
/**