Initial import of NODEDC BIM Viewer

This commit is contained in:
CODEX
2026-06-04 13:25:42 +03:00
commit 9aaf82862f
2075 changed files with 3592575 additions and 0 deletions
+209
View File
@@ -0,0 +1,209 @@
# 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`.