Camera
Камера сцены, доступная как scene.camera. Это Node, поэтому вся поверхность
трансформа работает — position, eulerAngles, lookAt, forward. Сверх этого она предоставляет
чтение проекции и помощники для лучей экран→мир для пикинга.
Ты её не конструируешь: каждая Scene создаёт свою камеру (оверлеи разделяют
камеру родителя). В ARScene камерой управляет трекинг устройства — читай её,
не размещай.
Обзор
scene.camera.position = [0, 2, 4]
scene.camera.lookAt([0, 0.5, 0])
scene.addEventListener('touchstart', ev => {
const ray = scene.camera.getRay(ev.clientX, ev.clientY)
const hit = Physics.raycast(ray.origin, ray.dir)
if (hit) console.log('tapped', hit.node?.name)
})Чтение проекции
camera.fov // вертикальное поле зрения, ГРАДУСЫ (только чтение)
camera.horizontalFov // горизонтальное поле зрения, градусы (только чтение)
camera.displaySize // [ширина, высота] 3D-вьюпорта, px (только чтение)
camera.projectionMatrix // Float32Array(16), живая — хост обновляет её на месте при ресайзе/смене fovЛучи экран → мир
camera.getViewDirection(screenX, screenY): Vec3 // направление луча в мире через экранную точку
camera.getRay(screenX, screenY): Ray // origin = camera.worldPosition, dir = направление взглядаЭкранные координаты — логические px — то же пространство, что ev.clientX / ev.clientY.
getRay напрямую сочетается с Physics.raycast для пикинга по тапу; Ray
описан в ray-plane-noise.
Note
помощника worldToScreen нет — обратная проекция доступна только сыро, через projectionMatrix +
worldMatrix камеры.
Подводные камни
// ✗ двигать камеру в ARScene — трекинг перезаписывает её каждый кадр
arScene.camera.position = [0, 2, 4]
// ✓ двигай вместо этого МИР: подвесь контент под scene.root и размести егоСмотрите также
- Scene — откуда берётся камера; оверлеи её разделяют.
- Node — унаследованная поверхность трансформа (
position,lookAt,forward). - 3D-физика и формы — рейкаст лучей, которые ты строишь здесь.
- Ray, Plane и Noise —
Ray, возвращаемыйgetRay.