210 lines
15 KiB
Markdown
210 lines
15 KiB
Markdown
# 25.12 Rotate / Switch Ortho Problems Report
|
||
|
||
Отчет составлен по содержимому чата и локальным изменениям кода в проекте.
|
||
Цель: зафиксировать весь путь расследования проблем с вращением (ось/pivot)
|
||
и прыжками камеры при переключении ортографической и перспективной проекции.
|
||
|
||
---
|
||
|
||
## 1. Подробное описание проблемы, наблюдений, логов и взаимосвязей
|
||
|
||
### 1.1 Контекст и среда
|
||
- Сцены очень крупные (километры), много LAS облаков, иногда GLB модели.
|
||
- Рабочий сценарий: уйти далеко, вернуться к объекту, переключать ortho/persp, вращать камеру.
|
||
- Пользователь каждый тест делает с очисткой кэша браузера. Сервер не перезапускается.
|
||
- На «свежем» состоянии проблемы часто не проявляются сразу, но появляются спустя время/навигацию.
|
||
|
||
### 1.2 Симптомы (что видит пользователь)
|
||
1) **Смещение оси вращения (pivot drift).**
|
||
- Вращение идет вокруг точки, которая не совпадает с курсором или целевым объектом.
|
||
- Часто ощущается, что точка вращения «за камерой» или сильно в стороне.
|
||
- В ortho проявляется чаще, но бывает и в perspective.
|
||
- Иногда исчезает после переключения в perspective или после фокуса (двойной клик).
|
||
|
||
2) **Прыжки камеры при переключении ortho <-> perspective.**
|
||
- При переключении камера уезжает назад или в сторону на 50–200+ метров.
|
||
- После прыжка новая дистанция становится «новой нормой» для следующих переключений.
|
||
- Особенно часто при переключении из ortho в perspective.
|
||
|
||
3) **Клиппинг (статические отсечки) в ortho.**
|
||
- Периодически появляется «плоскость отсечения», которая не зависит от зума.
|
||
- Отсечка исчезает при смене ракурса/переключении проекции, но может вернуться.
|
||
|
||
4) **Нестабильный зум (скачки шага).**
|
||
- После сильного отлета зум начинает «пропускать шаги».
|
||
- Приближение становится грубым: следующая позиция уже «за объектом».
|
||
|
||
### 1.3 Наблюдения (устойчивые повторения)
|
||
- Проблемы чаще всего возникают после **сильного отлета** и перемещения на большое расстояние.
|
||
- При аккуратной локальной работе (вокруг одного объекта) поведение обычно стабильнее.
|
||
- Переключение в perspective и небольшой «полет» иногда стабилизируют pivot.
|
||
- После double-click фокусировки проблемы временно исчезают.
|
||
|
||
### 1.4 Логи, которые использовались
|
||
В процессе добавлены и использовались флаги:
|
||
- `window.__dcProjDebug = true`
|
||
- `window.__dcPivotDebug = true`
|
||
- `window.__dcAllowOffsetEye = true` (опционально, для диагностики)
|
||
|
||
Типовые лог-сообщения:
|
||
- Проекции: `[dc-proj] persp->ortho`, `[dc-proj] ortho->persp`, `proj-switch(before/after)`
|
||
- Пивот: `[dc-pivot] start`, `[dc-pivot] start-clamp`, `[dc-pivot] ortho-pivot`, `[dc-pivot] persp-pick`, `[dc-pivot] ortho-eye-normalize`
|
||
|
||
Что замечено по логам:
|
||
- В ortho часто фиксируется **несоответствие между eyeLookDist и orthoScale** (orthoScale намного больше).
|
||
- В некоторых логах `pickDist`/`rayDist` сильно отличаются от `eyeLookDist`.
|
||
- Были ситуации, когда `pivotPos == look`, но ощущение вращения все равно «кривое»,
|
||
значит проблема не только в выборе pivot, а в состоянии камеры (eye/scale).
|
||
|
||
### 1.5 Взаимосвязи и гипотезы
|
||
Основные гипотезы, подтвержденные частично логами и наблюдениями:
|
||
- **Проблемы накопительные**: чем больше дальних перемещений и масштаба, тем выше шанс сломаться.
|
||
- **Пивот в ortho** при выборе через pick/ray нестабилен в больших сценах.
|
||
- **Сильные отлеты** приводят к разрыву между `orthoScale` и `eyeLookDist`, что искажает ось вращения.
|
||
- **Переключение проекций** использует параметры, которые не всегда согласованы с текущим состоянием камеры.
|
||
|
||
---
|
||
|
||
## 2. Подробное описание всех попыток исправления
|
||
|
||
Ниже приведены все попытки с указанием:
|
||
где делали, что меняли, зачем, ожидаемый результат и фактический результат.
|
||
|
||
### Попытка 1. Настройки клиппинга в UI (viewport)
|
||
**Где:** UI блок `Viewport` (инспектор).
|
||
**Что сделали:** добавили поля для клиппинга (perspective/ortho), позже min/max.
|
||
**Зачем:** пользователь видел слишком ранние отсечки и хотел управлять дистанцией.
|
||
**Ожидание:** контроль near/far клиппинга решит отсечки и приблизит камеру.
|
||
**Факт:** в perspective стало предсказуемее, в ortho появились «статические» отсечки,
|
||
которые не всегда зависели от камеры. Проблема клиппинга осталась.
|
||
|
||
### Попытка 2. Принудительный near/far (0.01 / 1e9)
|
||
**Где:** параметры камеры.
|
||
**Зачем:** исключить влияние near/far.
|
||
**Ожидание:** клиппинг исчезнет.
|
||
**Факт:** не помогло, отсечки остались.
|
||
|
||
### Попытка 3. Включение логов и сбор метрик
|
||
**Где:** консольный дебаг, далее встроенные логи.
|
||
**Что:** добавлены `[dc-proj]` и `[dc-pivot]` логи.
|
||
**Зачем:** видеть dist, orthoScale, pickDist, rayDist.
|
||
**Ожидание:** найти связь между параметрами и рывками/пивотом.
|
||
**Факт:** выявлены несоответствия scale/dist и роль сильных отлетов, но без прямого фикса.
|
||
|
||
### Попытка 4. Форк core-камеры в локальный файл
|
||
**Где:** `frontend/lib/dc-camera-context.es.js`
|
||
**Что:** из minified xeokit сделали локальную «контекстную» версию для правок.
|
||
**Зачем:** исправлять первоисточник, а не обертки.
|
||
**Ожидание:** полный контроль над Camera/Ortho/Perspective.
|
||
**Факт:** сначала ошибки сборки (duplicate identifier, lookAtMat4v undefined),
|
||
после коррекции файл заработал и стал основным местом правок.
|
||
|
||
### Попытка 5. Удаление обертки проекций
|
||
**Где:** `frontend/dcViewer.js`
|
||
**Что:** удален `projectionSync` (обертка синхронизации проекций).
|
||
**Зачем:** убрать внешние корректировки, которые могут конфликтовать.
|
||
**Ожидание:** меньше неожиданных прыжков.
|
||
**Факт:** источник конфликтов убран, но прыжки и pivot drift остались.
|
||
|
||
### Попытка 6. Пересчет ortho/persp в Camera.projection
|
||
**Где:** `frontend/lib/dc-camera-context.es.js` (Camera.projection setter)
|
||
**Что:**\n
|
||
- `persp -> ortho`: масштаб берется из `dist` и `fov`
|
||
- `ortho -> persp`: дистанция берется из `orthoScale` и `fov`
|
||
- убраны расчеты на основе `rayDist`
|
||
**Зачем:** сделать переключение более детерминированным.
|
||
**Ожидание:** стабильная дистанция при переключениях.
|
||
**Факт:** иногда лучше, но рывки оставались, особенно после большого зума.
|
||
|
||
### Попытка 7. Отключение offsetEyeFromLook
|
||
**Где:** `frontend/lib/dc-camera-context.es.js`
|
||
**Что:** `offsetEyeFromLook` теперь false по умолчанию, включается через флаг `__dcAllowOffsetEye`.
|
||
**Зачем:** offset подозревался как источник смещения оси вращения.
|
||
**Ожидание:** pivot станет стабильнее.
|
||
**Факт:** стало немного стабильнее, но проблема не исчезла.
|
||
|
||
### Попытка 8. Clamp pivot по dot/ratio
|
||
**Где:** `PivotController.startPivot`
|
||
**Что:** если pivotDist/eyeLookDist слишком большой или направление не совпадает,
|
||
pivot принудительно сбрасывается на `look`.
|
||
**Зачем:** исключить pivot за камерой.
|
||
**Ожидание:** уменьшение случаев «кривой» оси.
|
||
**Факт:** часть экстремальных случаев ушла, но проблема оставалась.
|
||
|
||
### Попытка 9. Эвристики ortho pick pivot
|
||
**Где:** обработчик mouse/touch для pivot в `dc-camera-context.es.js`
|
||
**Что:** pick pivot принимается только при нормальных dot/ratio и пределах `rayDist`.
|
||
**Зачем:** в ortho pick часто уводил pivot в неверное место.
|
||
**Ожидание:** меньше смещений оси.
|
||
**Факт:** поведение было нестабильным, в некоторых случаях хуже.
|
||
|
||
### Попытка 10. Ortho eye normalize
|
||
**Где:** `PivotController.startPivot`
|
||
**Что:** если `orthoScale >> eyeLookDist`, camera.eye отодвигается вдоль вида
|
||
на `max(eyeLookDist, orthoScale)`.
|
||
**Зачем:** уменьшить расхождение между масштабом и дистанцией камеры.
|
||
**Ожидание:** стабилизация оси вращения в ortho после сильного зума.
|
||
**Факт:** результаты неоднозначные, иногда хуже.
|
||
|
||
### Попытка 11. Полное отключение pick pivot в ortho (последняя правка)
|
||
**Где:** mouse/touch обработчики pivot в `dc-camera-context.es.js`
|
||
**Что:** при ortho pivot всегда `camera.look`, pick/ray не используются.
|
||
**Зачем:** убрать нестабильность pick pivot.
|
||
**Ожидание:** стабильная ось вращения в ortho.
|
||
**Факт:** требуется повторный тест после этой правки.
|
||
|
||
### Попытка 12. Жесткая фиксация `look` и движение `eye` вдоль направления
|
||
**Где:** `Camera.projection` setter
|
||
**Что:** при переключении проекций `look` фиксируется,
|
||
`eye` пересчитывается только по направлению вида (без боковых смещений).
|
||
**Зачем:** убрать скачки в сторону/назад при ortho <-> persp.
|
||
**Ожидание:** переключение без прыжков по позиции.
|
||
**Факт:** требуется повторный тест после этой правки.
|
||
|
||
### Попытка 13. Расширенные логи
|
||
**Где:** `dc-camera-context.es.js`
|
||
**Что:** добавлены детальные логи `[dc-proj]` и `[dc-pivot]`.
|
||
**Зачем:** фиксировать реальные параметры во время рывков.
|
||
**Ожидание:** получить воспроизводимые метрики для анализа.
|
||
**Факт:** помогло подтвердить связь с сильным зумом, но без полного решения.
|
||
|
||
---
|
||
|
||
## 3. Итоговое состояние на момент отчета
|
||
|
||
Актуальные изменения в форке:
|
||
- `frontend/lib/dc-camera-context.es.js`:
|
||
- упрощен пересчет ortho/persp;
|
||
- `offsetEyeFromLook` по умолчанию false;
|
||
- pivot clamp при подозрительном pivot;
|
||
- `ortho-eye-normalize` (эксперимент);
|
||
- **в ortho pivot всегда `look`**, pick/ray игнорируется (последняя правка);
|
||
- логи `__dcProjDebug` и `__dcPivotDebug`.
|
||
- `frontend/dcViewer.js`:
|
||
- удалена обертка `projectionSync`.
|
||
|
||
Состояние проблемы:
|
||
- после ряда правок поведение часто становится лучше на короткой дистанции,
|
||
но при сильных отлетах проблема возвращается.
|
||
- основной подозреваемый: накопление состояния в камере
|
||
+ разрыв между `orthoScale` и `eyeLookDist`
|
||
+ нежелательные pivot‑решения в ortho.
|
||
|
||
---
|
||
|
||
## 4. Что требуется для следующей итерации
|
||
1) Свежий тест после последних правок (без длительных старых сессий).
|
||
2) Логи:
|
||
- `window.__dcProjDebug = true`
|
||
- `window.__dcPivotDebug = true`
|
||
3) Сценарий:
|
||
- сильно отлететь,
|
||
- вернуться к объекту,
|
||
- вращать в ortho,
|
||
- переключить ortho/persp.
|
||
|
||
Если вновь поймается «кривая ось» или «скачок дистанции»,
|
||
лог должен сопровождать момент, чтобы анализировать разницу
|
||
между `eyeLookDist`, `orthoScale`, `pivotDist`, `pickDist`, `rayDist`.
|
||
|