OrbitView

Модель камеры и принцип OrbitView

OrbitView реализует орбитальную камеру, в которой сцена рассматривается как объект в центре координат, а камера движется по сферической траектории вокруг него. Такой подход характерен для 3D-визуализаций, где важна стабильная ориентация объекта и управляемый обзор без изменения внутренней логики сцены.

Ключевая особенность OrbitView — фиксированная точка наблюдения (target), вокруг которой вращается камера. В отличие от свободной 3D-навигации, здесь отсутствует произвольное перемещение камеры в пространстве: движение ограничено вращением, масштабированием и смещением цели.

Основные компоненты модели:

  • target — центр вращения камеры
  • rotation (yaw / pitch) — углы вращения вокруг осей
  • zoom / distance — расстояние до цели
  • up vector — направление «верха» сцены

Базовая конфигурация OrbitView

OrbitView подключается как один из типов view в системе Deck.gl и используется через класс OrbitView.

import {Deck} from '@deck.gl/core';
import {OrbitView} from '@deck.gl/core';

const deckgl = new Deck({
  views: new OrbitView({
    id: 'orbit-view'
  }),
  initialViewState: {
    target: [0, 0, 0],
    rotationX: 30,
    rotationOrbit: 45,
    zoom: 1
  },
  controller: true
});

Ключевые параметры initialViewState:

  • target — центр сцены
  • rotationX — наклон камеры по вертикали
  • rotationOrbit — вращение вокруг вертикальной оси
  • zoom — масштаб сцены

Геометрическая модель OrbitView

OrbitView использует сферические координаты для преобразования положения камеры:

  • радиус — расстояние до target
  • азимут — вращение вокруг вертикальной оси
  • зенит — вертикальный угол наклона

Перевод в декартовы координаты выполняется через тригонометрические преобразования:

  • x = r * cos(zenith) * cos(azimuth)
  • y = r * cos(zenith) * sin(azimuth)
  • z = r * sin(zenith)

Эта модель обеспечивает:

  • стабильное вращение вокруг центра
  • отсутствие «переворотов» камеры при корректных ограничениях углов
  • предсказуемое управление сценой

Параметры OrbitView и их влияние

target

target: [x, y, z]

Определяет точку, вокруг которой происходит орбитальное вращение.

Особенности:

  • изменение target смещает центр всей сцены
  • часто используется для фокусировки на объектах

rotationX

Вертикальный угол камеры.

  • положительные значения поднимают камеру вверх
  • отрицательные — опускают вниз
  • обычно ограничивается диапазоном [-90, 90]

rotationOrbit

Горизонтальное вращение вокруг сцены.

  • определяет направление обзора
  • изменяется при drag по горизонтали

zoom

Масштабирование сцены.

  • уменьшение zoom приближает камеру
  • увеличение zoom отдаляет

Важно: в OrbitView zoom часто нелинейный (логарифмическая шкала), что обеспечивает более естественное восприятие глубины.


Управление камерой

OrbitView интегрируется с controller системы Deck.gl, который обрабатывает пользовательский ввод:

controller: true

Типичные взаимодействия:

  • перетаскивание мышью — вращение вокруг target
  • колесо мыши — zoom
  • shift + drag — смещение target (pan)

События преобразуются в изменения viewState, что делает OrbitView реактивным компонентом.


Программное управление viewState

OrbitView может управляться полностью через состояние:

deckgl.setProps({
  viewState: {
    'orbit-view': {
      target: [10, 20, 0],
      rotationX: 45,
      rotationOrbit: 90,
      zoom: 2
    }
  }
});

Это позволяет:

  • реализовывать анимации камеры
  • создавать переходы между точками интереса
  • синхронизировать камеру с UI

Анимация камеры

OrbitView часто используется в сочетании с интерполяцией состояния камеры.

Пример линейного перехода:

function lerp(a, b, t) {
  return a + (b - a) * t;
}

const start = {rotationX: 10, rotationOrbit: 0, zoom: 1};
const end = {rotationX: 60, rotationOrbit: 180, zoom: 2};

const t = 0.5;

const viewState = {
  rotationX: lerp(start.rotationX, end.rotationX, t),
  rotationOrbit: lerp(start.rotationOrbit, end.rotationOrbit, t),
  zoom: lerp(start.zoom, end.zoom, t)
};

Используется для:

  • плавных переходов между объектами
  • cinematic-режимов
  • guided tours

Ограничения OrbitView

OrbitView не предназначен для свободной навигации в пространстве.

Ограничения:

  • отсутствие произвольного движения камеры
  • фиксированный центр вращения
  • невозможность «перелёта» через сцену без изменения target

Эти ограничения делают OrbitView особенно подходящим для:

  • CAD-визуализаций
  • 3D-моделей объектов
  • научной визуализации
  • архитектурных сцен

Связь с другими View в Deck.gl

OrbitView является частью системы многовидовой архитектуры Deck.gl.

Сравнение:

  • MapView — географические карты
  • FirstPersonView — навигация «от первого лица»
  • OrbitView — орбитальная камера вокруг объекта

OrbitView часто используется как базовый инструмент для 3D-слоёв, когда географическая привязка не требуется.


Использование с слоями (Layers)

OrbitView совместим со всеми 3D-слоями Deck.gl:

import {ScatterplotLayer} from '@deck.gl/layers';

const layer = new ScatterplotLayer({
  id: 'points',
  data: points,
  getPosition: d => d.position,
  getRadius: 10,
  getFillColor: [255, 0, 0]
});

Особенности:

  • координаты интерпретируются в пространстве view
  • глубина (z-axis) влияет на перспективу
  • поддерживается перспективная проекция

Работа с перспективой

OrbitView использует перспективную камеру, где объекты уменьшаются с расстоянием.

Ключевые параметры:

  • fieldOfView — угол обзора
  • near / far planes — границы отсечения

При слишком маленьком near или слишком большом far могут возникать:

  • z-fighting
  • потеря точности глубины

Оптимизация производительности

При использовании OrbitView в сложных сценах важны следующие аспекты:

1. Ограничение количества перерисовок

  • обновление viewState только при изменении ввода

2. Кэширование геометрии

  • предварительная генерация данных слоёв

3. Использование instanced rendering

  • для большого числа объектов

4. Контроль precision

  • оптимизация depth buffer через корректные near/far значения

Типичные ошибки при работе с OrbitView

Некорректный target

Если target не задан или равен нулевому вектору без смысла сцены:

  • камера вращается вокруг пустого пространства
  • теряется фокусировка

Перепутанные оси вращения

rotationX и rotationOrbit часто используются неправильно:

  • rotationX отвечает за вертикаль
  • rotationOrbit — за горизонт

Ошибки приводят к «перевёрнутым» сценам.


Слишком большой zoom диапазон

Избыточный zoom вызывает:

  • потерю глубины
  • пересечение near plane
  • визуальные артефакты

Пример комплексной сцены

import {Deck, OrbitView} from '@deck.gl/core';
import {CubeLayer} from '@deck.gl/mesh-layers';

const deckgl = new Deck({
  views: new OrbitView(),
  initialViewState: {
    target: [0, 0, 0],
    rotationX: 35,
    rotationOrbit: 45,
    zoom: 1.5
  },
  controller: true,
  layers: [
    new CubeLayer({
      data: [[0, 0, 0]],
      getPosition: d => d,
      getColor: [0, 128, 255]
    })
  ]
});

Управление сценами с несколькими OrbitView

Deck.gl позволяет использовать несколько view одновременно:

  • один OrbitView для основного объекта
  • второй для мини-карты или вспомогательной сцены
views: [
  new OrbitView({id: 'main'}),
  new OrbitView({id: 'secondary', x: 0, y: 0, width: '30%', height: '30%'})
]

Такой подход применяется в:

  • инженерных симуляциях
  • многомасштабной визуализации
  • аналитических панелях

Взаимодействие с шейдерами

OrbitView не изменяет шейдерную логику напрямую, но влияет на:

  • view matrix
  • projection matrix
  • model-view-projection pipeline

Все расчёты освещения и глубины зависят от положения камеры, заданного OrbitView, что делает его ключевым элементом 3D-пайплайна визуализации.