import { Box3, PerspectiveCamera, Vector3, Mesh, Camera } from 'three' import { degToRad } from 'three/src/math/MathUtils.js' export default function calculateScaleToFit( object: any, camera: ComputedRef, controls: any, distance: number, cameraOffset: { x: number; y: number; z: number } ) { // Создаем новый BoundingBox const bbox = new Box3() // Обновляем мировую матрицу объекта object.updateWorldMatrix(true, true) // Перебираем все дочерние элементы объекта object.traverse((child: any) => { if (child.isMesh) { // Добавляем геометрию каждого меша в bounding box const geometry = child.geometry if (geometry) { geometry.computeBoundingBox() // Убедимся, что bounding box геометрии вычислен const meshBBox = geometry.boundingBox.clone() if (meshBBox) { // Применяем мировую матрицу к bounding box meshBBox.applyMatrix4(child.matrixWorld) bbox.union(meshBBox) // Объединяем с общим bounding box } } } }) // Вычисляем центр и размер bounding box const center = new Vector3() bbox.getCenter(center) const size = new Vector3() bbox.getSize(size) // Центрируем объект object.position.sub(center) object.updateWorldMatrix(true, true) // Рассчитываем масштаб const fov = (camera.value as PerspectiveCamera).fov const aspect = (camera.value as PerspectiveCamera).aspect const vFOV = degToRad(fov) const visibleHeight = 2 * Math.tan(vFOV / 2) * distance const visibleWidth = visibleHeight * aspect const scaleX = visibleWidth / size.x const scaleY = visibleHeight / size.y const scaleZ = visibleWidth / size.z const scale = Math.min(scaleX, scaleY, scaleZ) // Масштабируем объект object.scale.setScalar(scale) object.updateWorldMatrix(true, true) if (camera.value) { const [x, y, z] = Object.values(cameraOffset).map(el => el * distance); camera.value.position.set(x, y, z); } // Настройка OrbitControls if (controls.value) { controls.value.target.set(...Object.values(center.multiplyScalar(1))) controls.value.update() } return object }