diff --git a/packages/frontend/src/pages/room.vue b/packages/frontend/src/pages/room.vue index 86ea118e9b..d4621df02a 100644 --- a/packages/frontend/src/pages/room.vue +++ b/packages/frontend/src/pages/room.vue @@ -27,19 +27,27 @@ SPDX-License-Identifier: AGPL-3.0-only -
+
{{ engine.selected.value.objectDef.name }} -
-
{{ s.label }}
-
- -
-
- -
-
- +
+
+
{{ s.label }}
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
@@ -69,6 +77,7 @@ import MkSelect from '@/components/MkSelect.vue'; import * as os from '@/os.js'; import MkInput from '@/components/MkInput.vue'; import MkSwitch from '@/components/MkSwitch.vue'; +import MkRange from '@/components/MkRange.vue'; const canvas = useTemplateRef('canvas'); diff --git a/packages/frontend/src/utility/room/engine.ts b/packages/frontend/src/utility/room/engine.ts index 5f54a2d2fb..0c81cce027 100644 --- a/packages/frontend/src/utility/room/engine.ts +++ b/packages/frontend/src/utility/room/engine.ts @@ -27,6 +27,7 @@ import { GridMaterial } from '@babylonjs/materials'; import { ShowInspector } from '@babylonjs/inspector'; import { reactive, ref, shallowRef, triggerRef, watch } from 'vue'; import { genId } from '../id.js'; +import { deepClone } from '../clone.js'; import { getObjectDef } from './object-defs.js'; import { HorizontalCameraKeyboardMoveInput } from './utility.js'; import * as sound from '@/utility/sound.js'; @@ -89,10 +90,30 @@ type EnumOptionSchema = { enum: string[]; }; -type OptionsSchema = Record; +type RangeOptionSchema = { + type: 'range'; + label: string; + min: number; + max: number; + step?: number; +}; + +type ImageOptionSchema = { + type: 'image'; + label: string; +}; + +type OptionsSchema = Record; type GetOptionsSchemaValues = { - [K in keyof T]: T[K] extends NumberOptionSchema ? number : T[K] extends BooleanOptionSchema ? boolean : T[K] extends ColorOptionSchema ? [number, number, number] : T[K] extends EnumOptionSchema ? T[K]['enum'][number] : never; + [K in keyof T]: + T[K] extends NumberOptionSchema ? number : + T[K] extends BooleanOptionSchema ? boolean : + T[K] extends ColorOptionSchema ? [number, number, number] : + T[K] extends EnumOptionSchema ? T[K]['enum'][number] : + T[K] extends RangeOptionSchema ? number : + T[K] extends ImageOptionSchema ? string | null : + never; }; type ObjectDef = { @@ -1144,12 +1165,14 @@ export class RoomEngine { const def = getObjectDef(type); + const options = deepClone(def.options.default); + const { root } = await this.loadObject({ id: id, type, position: new BABYLON.Vector3(0, 0, 0), rotation: new BABYLON.Vector3(0, Math.PI, 0), - options: def.options.default, + options, }); const ghost = this.createGhost(root); @@ -1197,7 +1220,7 @@ export class RoomEngine { position: [pos.x, pos.y, pos.z], rotation: [rotation.x, rotation.y, rotation.z], sticky, - options: def.options.default, + options, }); }, }; diff --git a/packages/frontend/src/utility/room/objects/pictureFrame.ts b/packages/frontend/src/utility/room/objects/pictureFrame.ts index bc9050d7ae..8701cec0bd 100644 --- a/packages/frontend/src/utility/room/objects/pictureFrame.ts +++ b/packages/frontend/src/utility/room/objects/pictureFrame.ts @@ -20,10 +20,31 @@ export const pictureFrame = defineObject({ label: 'Direction', enum: ['vertical', 'horizontal'], }, + matHThickness: { + type: 'range', + label: 'Mat horizontal thickness', + min: 0, + max: 1, + step: 0.01, + }, + matVThickness: { + type: 'range', + label: 'Mat vertical thickness', + min: 0, + max: 1, + step: 0.01, + }, + customPicture: { + type: 'image', + label: 'Custom picture', + }, }, default: { frameColor: [0.71, 0.58, 0.39], direction: 'vertical', + matHThickness: 0.125, + matVThickness: 0.15, + customPicture: null, }, }, placement: 'side', @@ -84,16 +105,30 @@ export const pictureFrame = defineObject({ applyDirection(); - //matMesh.morphTargetManager!.getTargetByName('MatH')!.influence = 0.6; - //matMesh.morphTargetManager!.getTargetByName('MatV')!.influence = 0.6; - //pictureMesh.morphTargetManager!.getTargetByName('PictureH')!.influence = 0.6; - //pictureMesh.morphTargetManager!.getTargetByName('PictureV')!.influence = 0.6; + const applyMatThickness = () => { + matMesh.morphTargetManager!.getTargetByName('MatH')!.influence = options.matHThickness; + matMesh.morphTargetManager!.getTargetByName('MatV')!.influence = options.matVThickness; + pictureMesh.morphTargetManager!.getTargetByName('PictureH')!.influence = options.matHThickness; + pictureMesh.morphTargetManager!.getTargetByName('PictureV')!.influence = options.matVThickness; + }; - const tex = new BABYLON.Texture('http://syu-win.local:3000/files/b6cefaba-3093-4c57-a7f8-993dee62c6f7', room.scene, false, false); + applyMatThickness(); const pictureMaterial = findMaterial('__X_PICTURE__'); - pictureMaterial.albedoColor = new BABYLON.Color3(1, 1, 1); - pictureMaterial.albedoTexture = tex; + + const applyCustomPicture = () => { + if (options.customPicture != null) { + const tex = new BABYLON.Texture(options.customPicture, room.scene, false, false); + + pictureMaterial.albedoColor = new BABYLON.Color3(1, 1, 1); + pictureMaterial.albedoTexture = tex; + } else { + pictureMaterial.albedoColor = new BABYLON.Color3(0.5, 0.5, 0.5); + pictureMaterial.albedoTexture = null; + } + }; + + applyCustomPicture(); const frameMaterial = findMaterial('__X_FRAME__'); @@ -115,6 +150,12 @@ export const pictureFrame = defineObject({ if (k === 'direction') { applyDirection(); } + if (k === 'matHThickness' || k === 'matVThickness') { + applyMatThickness(); + } + if (k === 'customPicture') { + applyCustomPicture(); + } }, interactions: {}, };