57 lines
2.4 KiB
TypeScript
57 lines
2.4 KiB
TypeScript
import { Box3, PerspectiveCamera, Vector3 } from 'three'
|
||
import { degToRad } from 'three/src/math/MathUtils.js';
|
||
|
||
/**
|
||
* Вычисляет масштаб объекта и позицию камеры, чтобы объект полностью помещался в видимой области.
|
||
* @param object - Объект Three.js (например, загруженная модель).
|
||
* @param camera - Экземпляр камеры.
|
||
* @param controls - Экземпляр OrbitControls.
|
||
* @param distance - Расстояние от камеры до объекта.
|
||
* @param cameraOffset - Коэффициенты смещения камеры (x, y, z).
|
||
*/
|
||
export default function (
|
||
object: any,
|
||
camera: PerspectiveCamera,
|
||
controls: any,
|
||
distance: number,
|
||
cameraOffset: { x: number; y: number; z: number }
|
||
) {
|
||
// Обновляем мировую матрицу объекта
|
||
object.updateWorldMatrix(true, true)
|
||
|
||
const fov = camera.fov // Угол обзора камеры
|
||
const aspect = camera.aspect // Соотношение сторон
|
||
|
||
const bbox = new Box3().setFromObject(object) // Вычисляем bounding box
|
||
const center = new Vector3()
|
||
bbox.getCenter(center) // Центр объекта
|
||
|
||
const size = new Vector3()
|
||
bbox.getSize(size) // Размеры объекта
|
||
|
||
// Рассчитываем масштаб, чтобы объект полностью помещался в видимой области
|
||
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)
|
||
|
||
// Позиционируем камеру с учетом смещения
|
||
camera.position.set(
|
||
center.x + distance * cameraOffset.x,
|
||
center.y + distance * cameraOffset.y,
|
||
center.z + distance * cameraOffset.z
|
||
)
|
||
|
||
// Устанавливаем цель для OrbitControls
|
||
if (controls) {
|
||
controls.target.set(center.x, center.y, center.z)
|
||
controls.update() // Обновляем контроллы
|
||
}
|
||
|
||
return { scale, center }
|
||
} |