diff --git a/packages/frontend/src/utility/room/objects/tv.ts b/packages/frontend/src/utility/room/objects/tv.ts index 874d3cd3fc..9e3cff0f7c 100644 --- a/packages/frontend/src/utility/room/objects/tv.ts +++ b/packages/frontend/src/utility/room/objects/tv.ts @@ -11,19 +11,52 @@ export const tv = defineObject({ id: 'tv', name: 'TV', options: { - schema: {}, - default: {}, + schema: { + screenBrightness: { + type: 'range', + label: 'Screen brightness', + min: 0, + max: 1, + step: 0.01, + }, + }, + default: { + screenBrightness: 0.5, + }, }, placement: 'top', - createInstance: ({ room, model }) => { + createInstance: ({ options, room, model, scene }) => { + const matrix = model.root.getWorldMatrix(true); + const scale = new BABYLON.Vector3(); + matrix.decompose(scale); + + const light = new BABYLON.SpotLight('', new BABYLON.Vector3(0/*cm*/, 30/*cm*/ / Math.abs(scale.y), 0), new BABYLON.Vector3(0, 0, 1), Math.PI / 1, 2, scene, room?.lightContainer != null); + light.parent = model.root; + light.diffuse = new BABYLON.Color3(1.0, 1.0, 1.0); + light.range = 150/*cm*/; + if (room?.lightContainer != null) room.lightContainer.addLight(light); + const screenMesh = model.findMesh('__TV_SCREEN__'); screenMesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true); model.bakeExcludeMeshes = [screenMesh]; - initTv(room, screenMesh); + const { material: screenMaterial } = initTv(room, screenMesh); + + const applyScreenBrightness = () => { + const b = options.screenBrightness; + screenMaterial.emissiveColor = new BABYLON.Color3(b, b, b); + light.intensity = 70000 * b; + }; + + applyScreenBrightness(); return { + onOptionsUpdated: ([k, v]) => { + switch (k) { + case 'screenBrightness': applyScreenBrightness(); break; + } + }, interactions: {}, }; }, diff --git a/packages/frontend/src/utility/room/utility.ts b/packages/frontend/src/utility/room/utility.ts index d12165677e..3206b5b836 100644 --- a/packages/frontend/src/utility/room/utility.ts +++ b/packages/frontend/src/utility/room/utility.ts @@ -282,21 +282,17 @@ const TV_PROGRAMS = { timeline: [index: number, duration: number][]; }>; -let tvScreenMaterial: BABYLON.PBRMaterial | null = null; - export function initTv(room: RoomEngine, screenMesh: BABYLON.Mesh) { const tvProgramId = 'shopping'; const tvProgram = TV_PROGRAMS[tvProgramId]; - if (tvScreenMaterial == null) { - tvScreenMaterial = new BABYLON.PBRMaterial('tvScreenMaterial', room.scene); - tvScreenMaterial.albedoColor = new BABYLON.Color3(0, 0, 0); - tvScreenMaterial.ambientColor = new BABYLON.Color3(0, 0, 0); - tvScreenMaterial.roughness = 1; - tvScreenMaterial.emissiveTexture = new BABYLON.Texture(`/client-assets/room/tv/${tvProgramId}/${tvProgramId}.png`, room.scene, false, false); - tvScreenMaterial.emissiveTexture.level = 1.0; - tvScreenMaterial.emissiveColor = new BABYLON.Color3(0.5, 0.5, 0.5); - tvScreenMaterial.freeze(); - } + const tvScreenMaterial = new BABYLON.PBRMaterial('tvScreenMaterial', room.scene); + tvScreenMaterial.albedoColor = new BABYLON.Color3(0, 0, 0); + tvScreenMaterial.ambientColor = new BABYLON.Color3(0, 0, 0); + tvScreenMaterial.roughness = 1; + tvScreenMaterial.emissiveTexture = new BABYLON.Texture(`/client-assets/room/tv/${tvProgramId}/${tvProgramId}.png`, room.scene, false, false); + tvScreenMaterial.emissiveTexture.level = 1.0; + tvScreenMaterial.emissiveColor = new BABYLON.Color3(0.5, 0.5, 0.5); + tvScreenMaterial.freeze(); const uvs = screenMesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; const uvIndexes = getPlaneUvIndexes(screenMesh); @@ -338,6 +334,13 @@ export function initTv(room: RoomEngine, screenMesh: BABYLON.Mesh) { }; applyTvTexture(0); + + return { + material: tvScreenMaterial, + dispose() { + tvScreenMaterial.dispose(); + }, + }; } /**