From fad53328bee32602ad6737f99211da574adf884a Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Thu, 28 May 2026 17:42:54 +0900
Subject: [PATCH] wip
---
.../src/PlayerContainer.ts | 2 ++
.../src/avatarPreviewEngine.ts | 33 ++++++++-----------
.../components/MkWorldAvatarEditDialog.vue | 21 +++++-------
3 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/packages/frontend-misskey-world-engine/src/PlayerContainer.ts b/packages/frontend-misskey-world-engine/src/PlayerContainer.ts
index 5eb291d92e..498b9cdda7 100644
--- a/packages/frontend-misskey-world-engine/src/PlayerContainer.ts
+++ b/packages/frontend-misskey-world-engine/src/PlayerContainer.ts
@@ -69,6 +69,8 @@ export class PlayerContainer {
this.subRoot = new BABYLON.TransformNode(`player:${this.id}:subRoot`, params.scene);
this.subRoot.parent = this.subRootContainerForAnim;
if (params.state) this.applyState(params.state, true);
+
+ console.log('PlayerContainer created', this.id);
}
public async loadAvatar() {
diff --git a/packages/frontend-misskey-world-engine/src/avatarPreviewEngine.ts b/packages/frontend-misskey-world-engine/src/avatarPreviewEngine.ts
index b436c82d96..b4d421773e 100644
--- a/packages/frontend-misskey-world-engine/src/avatarPreviewEngine.ts
+++ b/packages/frontend-misskey-world-engine/src/avatarPreviewEngine.ts
@@ -9,6 +9,7 @@ import { cm, WORLD_SCALE } from 'misskey-world/src/utility.js';
import { ArcRotateCameraManualInput, getMeshesBoundingBox, GRAPHICS_QUALITY } from './utility.js';
import { PlayerContainer, type PlayerProfile } from './PlayerContainer.js';
import { EngineBase } from './EngineBase.js';
+import { deepClone } from './clone.js';
import type { WorldAvatar } from 'misskey-world/src/types.js';
export class AvatarPreviewEngine extends EngineBase<{ // PlayerPreviewEngineに改名した方がいいかもしれない
@@ -39,7 +40,7 @@ export class AvatarPreviewEngine extends EngineBase<{ // PlayerPreviewEngineに
registerBuiltInLoaders();
this.graphicsQuality = options.graphicsQuality;
- this.profile = profile;
+ this.profile = deepClone(profile);
this.scene.autoClear = false;
this.scene.skipPointerMovePicking = true;
@@ -48,7 +49,16 @@ export class AvatarPreviewEngine extends EngineBase<{ // PlayerPreviewEngineに
this.sr = new BABYLON.SnapshotRenderingHelper(this.scene);
- this.camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 2.5, cm(300), new BABYLON.Vector3(0, cm(90), 0), this.scene);
+ this.camera = new BABYLON.ArcRotateCamera('camera', Math.PI / 2, Math.PI / 2.5, cm(300), new BABYLON.Vector3(0, cm(90), 0), this.scene);
+ this.camera.minZ = cm(1);
+ this.camera.maxZ = cm(100000);
+ this.camera.fov = 0.5;
+ this.camera.lowerRadiusLimit = cm(50);
+ this.camera.upperRadiusLimit = cm(1000);
+ this.camera.inputs.clear();
+ this.camera.inputs.add(new ArcRotateCameraManualInput(this.scene, {
+ rotationSensitivity: 0.0005,
+ }));
this.envMapIndoor = BABYLON.CubeTexture.CreateFromPrefilteredData('/client-assets/room/indoor.env', this.scene);
this.envMapIndoor.boundingBoxSize = new BABYLON.Vector3(cm(500), cm(500), cm(500));
@@ -151,29 +161,12 @@ export class AvatarPreviewEngine extends EngineBase<{ // PlayerPreviewEngineに
const boundingInfo = getMeshesBoundingBox(this.playerContainer.root.getChildMeshes().filter(m => m.isEnabled() && m.isVisible), true);
- this.pipeline.removeCamera(this.camera);
- this.camera.dispose();
-
- this.camera = new BABYLON.ArcRotateCamera('camera', Math.PI / 2, Math.PI / 2.5, cm(300), new BABYLON.Vector3(0, cm(90), 0), this.scene);
- this.camera.minZ = cm(1);
- this.camera.maxZ = cm(100000);
- this.camera.fov = 0.5;
- this.camera.lowerRadiusLimit = cm(50);
- this.camera.upperRadiusLimit = cm(1000);
- //this.camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
this.camera.setTarget(new BABYLON.Vector3(0, boundingInfo.centerWorld.y, 0));
- this.camera.inputs.clear();
-
- this.camera.inputs.add(new ArcRotateCameraManualInput(this.scene, {
- rotationSensitivity: 0.0005,
- }));
// zoom to fit
const size = boundingInfo.extendSize;
const distance = Math.max(size.x, size.y, size.z) * 2;
- this.camera.radius = distance * 3;
-
- this.pipeline.addCamera(this.camera);
+ this.camera.radius = distance * 4;
this.sr.enableSnapshotRendering();
}
diff --git a/packages/frontend/src/components/MkWorldAvatarEditDialog.vue b/packages/frontend/src/components/MkWorldAvatarEditDialog.vue
index 9fbfaa572b..a33c142744 100644
--- a/packages/frontend/src/components/MkWorldAvatarEditDialog.vue
+++ b/packages/frontend/src/components/MkWorldAvatarEditDialog.vue
@@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._miWorld._avatars._default.body }}
- { const c = getRgb(v); if (c != null) avatar.body.color = c; }">
+ { const c = getRgb(v); if (c != null) avatar.body.color = c; updateAvatarOption(); }">
{{ i18n.ts.color }}
@@ -61,12 +61,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{ label: 'e', value: 'e' },
{ label: 'f', value: 'f' },
{ label: 'g', value: 'g' },
- ]" :modelValue="avatar.eyes.type" @update:modelValue="v => avatar.eyes.type = v"
+ ]" :modelValue="avatar.eyes.type" @update:modelValue="v => { avatar.eyes.type = v; updateAvatarOption(); }"
>
{{ i18n.ts.type }}
- { const c = getRgb(v); if (c != null) avatar.eyes.color = c; }">
+ { const c = getRgb(v); if (c != null) avatar.eyes.color = c; updateAvatarOption(); }">
{{ i18n.ts.color }}
@@ -83,12 +83,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{ label: 'd', value: 'd' },
{ label: 'e', value: 'e' },
{ label: 'f', value: 'f' },
- ]" :modelValue="avatar.mouth.type" @update:modelValue="v => avatar.mouth.type = v"
+ ]" :modelValue="avatar.mouth.type" @update:modelValue="v => { avatar.mouth.type = v; updateAvatarOption(); }"
>
{{ i18n.ts.type }}
- { const c = getRgb(v); if (c != null) avatar.mouth.color = c; }">
+ { const c = getRgb(v); if (c != null) avatar.mouth.color = c; updateAvatarOption(); }">
{{ i18n.ts.color }}
@@ -172,10 +172,6 @@ const avatarPreviewEngineControllerOptions = computed {
- controller.updateAvatar(avatar.value);
-}, { deep: true });
-
onMounted(async () => {
try {
await controller.init(canvas.value!, {
@@ -201,10 +197,9 @@ onUnmounted(() => {
controller.destroy();
});
-//function updateAvatarOption(k: string, v: any) {
-// avatar.value[k] = v;
-// controller.updateAvatar(avatar.value);
-//}
+function updateAvatarOption() {
+ controller.updateAvatar(avatar.value);
+}
function ok() {
emit('ok', {