NODEDC_BIM_VIEWER/report/251220RotateSwitchOrtoProbl...

210 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.**
- При переключении камера уезжает назад или в сторону на 50200+ метров.
- После прыжка новая дистанция становится «новой нормой» для следующих переключений.
- Особенно часто при переключении из 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`.