diff --git a/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.blend b/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.blend new file mode 100644 index 0000000000..5299a8f334 Binary files /dev/null and b/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.blend differ diff --git a/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.glb b/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.glb new file mode 100644 index 0000000000..a5890859fb Binary files /dev/null and b/packages/frontend/assets/room/objects/wall-mirror/wall-mirror.glb differ diff --git a/packages/frontend/src/utility/room/object-defs.ts b/packages/frontend/src/utility/room/object-defs.ts index ff0a9488f6..9f9c29b7fa 100644 --- a/packages/frontend/src/utility/room/object-defs.ts +++ b/packages/frontend/src/utility/room/object-defs.ts @@ -71,6 +71,7 @@ import { tetrapod } from './objects/tetrapod.js'; import { tv } from './objects/tv.js'; import { wallCanvas } from './objects/wallCanvas.js'; import { wallClock } from './objects/wallClock.js'; +import { wallMirror } from './objects/wallMirror.js'; import { wallShelf } from './objects/wallShelf.js'; import { woodRingFloorLamp } from './objects/woodRingFloorLamp.js'; import { woodSoundAbsorbingPanel } from './objects/woodSoundAbsorbingPanel.js'; @@ -143,6 +144,7 @@ export const OBJECT_DEFS = [ tv, wallCanvas, wallClock, + wallMirror, wallShelf, woodRingFloorLamp, woodSoundAbsorbingPanel, diff --git a/packages/frontend/src/utility/room/objects/wallMirror.ts b/packages/frontend/src/utility/room/objects/wallMirror.ts new file mode 100644 index 0000000000..b9513e8f5e --- /dev/null +++ b/packages/frontend/src/utility/room/objects/wallMirror.ts @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as BABYLON from '@babylonjs/core'; +import { defineObject } from '../engine.js'; + +export const wallMirror = defineObject({ + id: 'wallMirror', + name: 'wallMirror', + options: { + schema: { + width: { + type: 'range', + label: 'Width', + min: 0, + max: 1, + step: 0.01, + }, + height: { + type: 'range', + label: 'Height', + min: 0, + max: 1, + step: 0.01, + }, + frameThickness: { + type: 'range', + label: 'Frame thickness', + min: 0, + max: 1, + step: 0.01, + }, + frameColor: { + type: 'color', + label: 'Frame color', + }, + }, + default: { + width: 0.2, + height: 0.2, + frameThickness: 0.1, + frameColor: [0.8, 0.28, 0.06], + }, + }, + placement: 'side', + createInstance: async ({ options, model }) => { + const frameMaterial = model.findMaterial('__X_FRAME__'); + const frameMesh = model.findMesh('__X_FRAME__'); + const mirrorMesh = model.findMesh('__X_MIRROR__'); + + const applySize = () => { + frameMesh.morphTargetManager!.getTargetByName('Width')!.influence = options.width; + frameMesh.morphTargetManager!.getTargetByName('Height')!.influence = options.height; + frameMesh.morphTargetManager!.getTargetByName('FrameThickness')!.influence = options.frameThickness; + mirrorMesh.morphTargetManager!.getTargetByName('Width')!.influence = options.width; + mirrorMesh.morphTargetManager!.getTargetByName('Height')!.influence = options.height; + model.updated(); + }; + + applySize(); + + const applyFrameColor = () => { + frameMaterial.albedoColor = new BABYLON.Color3(...options.frameColor); + }; + + applyFrameColor(); + + return { + onInited: () => { + + }, + onOptionsUpdated: ([k, v]) => { + switch (k) { + case 'width': + case 'height': + case 'frameThickness': + applySize(); + break; + case 'frameColor': + applyFrameColor(); + break; + } + }, + interactions: {}, + }; + }, +});