From 208c300460edc4741f0d1d5e6cfeabd39d054a3d Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:22:56 +0900 Subject: [PATCH] refactor --- .../src/utility/room/objects/pictureFrame.ts | 93 +----------------- .../src/utility/room/objects/poster.ts | 93 +----------------- .../src/utility/room/objects/tapestry.ts | 93 +----------------- packages/frontend/src/utility/room/utility.ts | 98 +++++++++++++++++++ 4 files changed, 107 insertions(+), 270 deletions(-) diff --git a/packages/frontend/src/utility/room/objects/pictureFrame.ts b/packages/frontend/src/utility/room/objects/pictureFrame.ts index f3e37bddc7..1fc67f2169 100644 --- a/packages/frontend/src/utility/room/objects/pictureFrame.ts +++ b/packages/frontend/src/utility/room/objects/pictureFrame.ts @@ -5,7 +5,7 @@ import * as BABYLON from '@babylonjs/core'; import { defineObject } from '../engine.js'; -import { getPlaneUvIndexes } from '../utility.js'; +import { createPlaneUvMapper, getPlaneUvIndexes } from '../utility.js'; export const pictureFrame = defineObject({ id: 'pictureFrame', @@ -84,21 +84,10 @@ export const pictureFrame = defineObject({ coverMesh.rotationQuaternion = null; const pictureMesh = findMesh('__X_PICTURE__'); pictureMesh.rotationQuaternion = null; - pictureMesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true); const pictureMaterial = findMaterial('__X_PICTURE__'); - const uvs = pictureMesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; - const uvIndexes = getPlaneUvIndexes(pictureMesh); - - const ax = uvs[uvIndexes[0]]; - const ay = uvs[uvIndexes[0] + 1]; - const bx = uvs[uvIndexes[1]]; - const by = uvs[uvIndexes[1] + 1]; - const cx = uvs[uvIndexes[2]]; - const cy = uvs[uvIndexes[2] + 1]; - const dx = uvs[uvIndexes[3]]; - const dy = uvs[uvIndexes[3] + 1]; + const updateUv = createPlaneUvMapper(pictureMesh); const applyFit = () => { const tex = pictureMaterial.albedoTexture; @@ -111,83 +100,7 @@ export const pictureFrame = defineObject({ const targetHeight = options.height * (1 - (options.matVThickness * MAT_THICKNESS_FACTOR)); const targetAspect = targetWidth / targetHeight; - let newAx = ax; - let newAy = ay; - let newBx = bx; - let newBy = by; - let newCx = cx; - let newCy = cy; - let newDx = dx; - let newDy = dy; - - if (options.fit === 'cover') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio < 1) { - uRange = ratio; // < 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // < 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } else if (options.fit === 'contain') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio > 1) { - uRange = ratio; // > 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // > 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } - - uvs[uvIndexes[0]] = newAx; - uvs[uvIndexes[0] + 1] = newAy; - uvs[uvIndexes[1]] = newBx; - uvs[uvIndexes[1] + 1] = newBy; - uvs[uvIndexes[2]] = newCx; - uvs[uvIndexes[2] + 1] = newCy; - uvs[uvIndexes[3]] = newDx; - uvs[uvIndexes[3] + 1] = newDy; - - pictureMesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs); + updateUv(srcAspect, targetAspect, options.fit); }; applyFit(); diff --git a/packages/frontend/src/utility/room/objects/poster.ts b/packages/frontend/src/utility/room/objects/poster.ts index 876f09fdda..acdb8073ce 100644 --- a/packages/frontend/src/utility/room/objects/poster.ts +++ b/packages/frontend/src/utility/room/objects/poster.ts @@ -5,7 +5,7 @@ import * as BABYLON from '@babylonjs/core'; import { defineObject } from '../engine.js'; -import { getPlaneUvIndexes } from '../utility.js'; +import { createPlaneUvMapper, getPlaneUvIndexes } from '../utility.js'; export const poster = defineObject({ id: 'poster', @@ -47,23 +47,12 @@ export const poster = defineObject({ createInstance: ({ room, root, options, findMaterial, findMesh, findMeshes, meshUpdated }) => { const pictureMesh = findMesh('__X_PICTURE__'); pictureMesh.rotationQuaternion = null; - pictureMesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true); const pictureMaterial = findMaterial('__X_PICTURE__'); const pinMeshes = findMeshes('__X_PIN__'); - const uvs = pictureMesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; - const uvIndexes = getPlaneUvIndexes(pictureMesh); - - const ax = uvs[uvIndexes[0]]; - const ay = uvs[uvIndexes[0] + 1]; - const bx = uvs[uvIndexes[1]]; - const by = uvs[uvIndexes[1] + 1]; - const cx = uvs[uvIndexes[2]]; - const cy = uvs[uvIndexes[2] + 1]; - const dx = uvs[uvIndexes[3]]; - const dy = uvs[uvIndexes[3] + 1]; + const updateUv = createPlaneUvMapper(pictureMesh); const applyFit = () => { const tex = pictureMaterial.albedoTexture; @@ -76,83 +65,7 @@ export const poster = defineObject({ const targetHeight = options.height; const targetAspect = targetWidth / targetHeight; - let newAx = ax; - let newAy = ay; - let newBx = bx; - let newBy = by; - let newCx = cx; - let newCy = cy; - let newDx = dx; - let newDy = dy; - - if (options.fit === 'cover') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio < 1) { - uRange = ratio; // < 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // < 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } else if (options.fit === 'contain') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio > 1) { - uRange = ratio; // > 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // > 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } - - uvs[uvIndexes[0]] = newAx; - uvs[uvIndexes[0] + 1] = newAy; - uvs[uvIndexes[1]] = newBx; - uvs[uvIndexes[1] + 1] = newBy; - uvs[uvIndexes[2]] = newCx; - uvs[uvIndexes[2] + 1] = newCy; - uvs[uvIndexes[3]] = newDx; - uvs[uvIndexes[3] + 1] = newDy; - - pictureMesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs); + updateUv(srcAspect, targetAspect, options.fit); }; applyFit(); diff --git a/packages/frontend/src/utility/room/objects/tapestry.ts b/packages/frontend/src/utility/room/objects/tapestry.ts index d2ecf611ba..074f808d3d 100644 --- a/packages/frontend/src/utility/room/objects/tapestry.ts +++ b/packages/frontend/src/utility/room/objects/tapestry.ts @@ -5,7 +5,7 @@ import * as BABYLON from '@babylonjs/core'; import { defineObject } from '../engine.js'; -import { getPlaneUvIndexes } from '../utility.js'; +import { createPlaneUvMapper, getPlaneUvIndexes } from '../utility.js'; export const tapestry = defineObject({ id: 'tapestry', @@ -47,7 +47,6 @@ export const tapestry = defineObject({ createInstance: ({ room, root, options, findMaterial, findMesh, findMeshes, meshUpdated }) => { const pictureMesh = findMesh('__X_PICTURE__'); pictureMesh.rotationQuaternion = null; - pictureMesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true); const pipeTopMesh = findMesh('__X_PIPE_TOP__'); const pipeBottomMesh = findMesh('__X_PIPE_BOTTOM__'); @@ -55,17 +54,7 @@ export const tapestry = defineObject({ const pictureMaterial = findMaterial('__X_PICTURE__'); - const uvs = pictureMesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; - const uvIndexes = getPlaneUvIndexes(pictureMesh); - - const ax = uvs[uvIndexes[0]]; - const ay = uvs[uvIndexes[0] + 1]; - const bx = uvs[uvIndexes[1]]; - const by = uvs[uvIndexes[1] + 1]; - const cx = uvs[uvIndexes[2]]; - const cy = uvs[uvIndexes[2] + 1]; - const dx = uvs[uvIndexes[3]]; - const dy = uvs[uvIndexes[3] + 1]; + const updateUv = createPlaneUvMapper(pictureMesh); const applyFit = () => { const tex = pictureMaterial.albedoTexture; @@ -78,83 +67,7 @@ export const tapestry = defineObject({ const targetHeight = options.height; const targetAspect = targetWidth / targetHeight; - let newAx = ax; - let newAy = ay; - let newBx = bx; - let newBy = by; - let newCx = cx; - let newCy = cy; - let newDx = dx; - let newDy = dy; - - if (options.fit === 'cover') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio < 1) { - uRange = ratio; // < 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // < 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } else if (options.fit === 'contain') { - const ratio = targetAspect / srcAspect; - - let uRange: number; - let vRange: number; - - if (ratio > 1) { - uRange = ratio; // > 1 - vRange = 1; - } else { - uRange = 1; - vRange = 1 / ratio; // > 1 - } - - const uMin = (1 - uRange) / 2; - const uMax = uMin + uRange; - const vMin = (1 - vRange) / 2; - const vMax = vMin + vRange; - - newAx = uMin; - newBx = uMax; - newCx = uMin; - newDx = uMax; - - newAy = 1 - vMax; - newBy = 1 - vMax; - newCy = 1 - vMin; - newDy = 1 - vMin; - } - - uvs[uvIndexes[0]] = newAx; - uvs[uvIndexes[0] + 1] = newAy; - uvs[uvIndexes[1]] = newBx; - uvs[uvIndexes[1] + 1] = newBy; - uvs[uvIndexes[2]] = newCx; - uvs[uvIndexes[2] + 1] = newCy; - uvs[uvIndexes[3]] = newDx; - uvs[uvIndexes[3] + 1] = newDy; - - pictureMesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs); + updateUv(srcAspect, targetAspect, options.fit); }; applyFit(); diff --git a/packages/frontend/src/utility/room/utility.ts b/packages/frontend/src/utility/room/utility.ts index 2ebb16b4ca..b8a4f5c815 100644 --- a/packages/frontend/src/utility/room/utility.ts +++ b/packages/frontend/src/utility/room/utility.ts @@ -369,3 +369,101 @@ export function getPlaneUvIndexes(mesh: BABYLON.Mesh) { return [aIndex, bIndex, cIndex, dIndex]; } + +export function createPlaneUvMapper(mesh: BABYLON.Mesh) { + mesh.markVerticesDataAsUpdatable(BABYLON.VertexBuffer.UVKind, true); + + const uvs = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind)!; + const uvIndexes = getPlaneUvIndexes(mesh); + + const ax = uvs[uvIndexes[0]]; + const ay = uvs[uvIndexes[0] + 1]; + const bx = uvs[uvIndexes[1]]; + const by = uvs[uvIndexes[1] + 1]; + const cx = uvs[uvIndexes[2]]; + const cy = uvs[uvIndexes[2] + 1]; + const dx = uvs[uvIndexes[3]]; + const dy = uvs[uvIndexes[3] + 1]; + + return (srcAspect: number, targetAspect: number, method: 'cover' | 'contain' | 'stretch') => { + let newAx = ax; + let newAy = ay; + let newBx = bx; + let newBy = by; + let newCx = cx; + let newCy = cy; + let newDx = dx; + let newDy = dy; + + if (method === 'cover') { + const ratio = targetAspect / srcAspect; + + let uRange: number; + let vRange: number; + + if (ratio < 1) { + uRange = ratio; // < 1 + vRange = 1; + } else { + uRange = 1; + vRange = 1 / ratio; // < 1 + } + + const uMin = (1 - uRange) / 2; + const uMax = uMin + uRange; + const vMin = (1 - vRange) / 2; + const vMax = vMin + vRange; + + newAx = uMin; + newBx = uMax; + newCx = uMin; + newDx = uMax; + + newAy = 1 - vMax; + newBy = 1 - vMax; + newCy = 1 - vMin; + newDy = 1 - vMin; + } else if (method === 'contain') { + const ratio = targetAspect / srcAspect; + + let uRange: number; + let vRange: number; + + if (ratio > 1) { + uRange = ratio; // > 1 + vRange = 1; + } else { + uRange = 1; + vRange = 1 / ratio; // > 1 + } + + const uMin = (1 - uRange) / 2; + const uMax = uMin + uRange; + const vMin = (1 - vRange) / 2; + const vMax = vMin + vRange; + + newAx = uMin; + newBx = uMax; + newCx = uMin; + newDx = uMax; + + newAy = 1 - vMax; + newBy = 1 - vMax; + newCy = 1 - vMin; + newDy = 1 - vMin; + } else if (method === 'stretch') { + // nop + } + + uvs[uvIndexes[0]] = newAx; + uvs[uvIndexes[0] + 1] = newAy; + uvs[uvIndexes[1]] = newBx; + uvs[uvIndexes[1] + 1] = newBy; + uvs[uvIndexes[2]] = newCx; + uvs[uvIndexes[2] + 1] = newCy; + uvs[uvIndexes[3]] = newDx; + uvs[uvIndexes[3] + 1] = newDy; + + mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs); + }; +}