fix: physical conveyor realism - belt at 0.7m, item rides ON belt

- Create physicalLayout.ts with all dimensions
- Update conveyorPath.ts to use correct belt height
- Rebuild ConveyorBelt with support legs, rollers, drive motor
- Item Y = BELT_TOP_Y + itemHeight/2
This commit is contained in:
root
2026-07-09 14:21:00 +02:00
parent 35138c824c
commit fa770f9da9
17 changed files with 923 additions and 175 deletions

View File

@@ -0,0 +1,197 @@
# Light Scene Fix Report
**Date:** 2026-07-09
**Status:** Fixed
---
## Problem
1. **Dark scene** — почти чёрный фон, плохая видимость
2. **"Лестница из труб"** — вращающийся артефакт на конвейере
---
## Root Cause: "Лестница из труб"
**Проблема в `ConveyorBelt` компоненте:**
```tsx
// БЫЛО — вся группа роликов вращалась вокруг Z:
<group ref={rollersRef}>
{Array.from({ length: 18 }).map((_, i) => (
<mesh key={i} position={[...]} rotation={[Math.PI / 2, 0, 0]}>
<cylinderGeometry args={[...]} />
</mesh>
))}
</group>
useFrame(() => {
rollersRef.current.rotation.z += delta; // ← ВСЯ ГРУППА вращалась!
});
```
Это создавало эффект "вращающейся лестницы" — все 18 роликов крутились вокруг общей оси Z.
**Исправление:**
```tsx
// СТАЛО — каждый ролик вращается отдельно вокруг своей оси X:
function Roller({ position, speedFactor }) {
const meshRef = useRef<Mesh>(null);
useFrame((_, delta) => {
meshRef.current.rotation.x += delta * speedFactor * 3;
});
return <mesh ref={meshRef} rotation={[0, 0, Math.PI/2]} ... />;
}
// + добавлены animated stripes на ленте
function BeltStripe({ offset, speedFactor }) { ... }
```
---
## Files Changed
| File | Changes |
|------|---------|
| `src/components/ThreeD/SorterDigitalTwinContinuous.tsx` | Complete rewrite with light palette |
| `scripts/test_light_scene.py` | Browser QA script |
---
## Color Palette Changes
| Element | Before | After |
|---------|--------|-------|
| Background | `#0a1520` (dark) | `#f6f9ff` (light blue-white) |
| Floor | `#0f1a2a` (dark) | `#eaf2ff` (light blue) |
| Grid | `#2a4a6a` | `#c9d8ee` |
| Belt | `#1a2836` (dark) | `#7aa2d8` (medium blue) |
| Side guards | `#2a3d52` (dark) | `#9bb7d8` (light blue) |
| Rollers | `#3a5068` (dark) | `#b7c8dc` (light gray-blue) |
| Frame | — | `#d8e6f8` (very light blue) |
**Route colors (kept bright):**
- B: `#22c55e` (green)
- C: `#f97316` (orange)
- D: `#8b5cf6` (purple)
---
## Lighting Changes
| Light | Before | After |
|-------|--------|-------|
| Ambient | 0.6 | 0.9 |
| Directional (main) | 1.0 | 1.2 |
| Directional (fill) | 0.3 | 0.5 |
| Hemisphere | 0.25 | 0.6 |
---
## Animation Changes
| Animation | Before | After |
|-----------|--------|-------|
| Rollers | Group rotation.z (broken) | Individual rotation.x (correct) |
| Belt motion | None | Moving stripes |
| Speed | N/A | ~1 m/s visual speed |
---
## Production Verification
```
curl -I https://arhipovdan.ru/ → 200 OK
curl -I https://arhipovdan.ru/details → 200 OK
```
**Browser QA:**
- ✓ Light background
- ✓ No dark scene
- ✓ No "ladder" artifact
- ✓ Conveyor reads as belt
- ✓ Item visible
- ✓ Play works
- ✓ HUD readable
- ✓ /details not broken
- ✓ No console errors
---
## Screenshots
```
docs/light_scene_screenshots/
├── light_idle.png
├── light_play_started.png
├── light_running_3s.png
└── light_route_active.png
```
### light_idle.png
- Light blue-white background
- Clean conveyor belt
- Zones A, B, C, D visible
- HUD readable on dark panel
### light_route_active.png
- Case 2/8 running
- Item visible (green for B)
- Gate bar colored by category
- Status updates in HUD
---
## Build/Test Results
```
✓ npm run build — success
✓ npm run test — 59 tests passed
✓ docker rebuild — success
✓ Production deployed
```
---
## What Remains
- Fine-tune roller rotation speed if needed
- Optional: add subtle shadow under items
- Optional: camera auto-follow during routing
---
## Commands for Commit/Push
```bash
cd /opt/arhipovdan/app
git add \
src/components/ThreeD/SorterDigitalTwinContinuous.tsx \
scripts/test_light_scene.py \
docs/LIGHT_SCENE_FIX_REPORT.md \
docs/light_scene_screenshots/
git commit -m "$(cat <<'EOF'
fix: light warehouse-style 3D scene, remove rotating ladder artifact
Root cause: ConveyorBelt used group.rotation.z which rotated all 18
rollers together, creating a "rotating ladder" visual artifact.
Fix:
- Each roller now rotates independently around its own X axis
- Added moving belt stripes for visual motion
- Changed dark palette (#0a1520) to light (#f6f9ff)
- Increased ambient/directional lighting
- Conveyor now looks like actual warehouse belt
Tested on https://arhipovdan.ru/ — light scene, no artifacts
EOF
)"
git push origin dan_branch
```
**DO NOT RUN** — commit/push not requested.

View File

@@ -0,0 +1,124 @@
# Physical Conveyor Report
## Summary
Исправлена физическая правдоподобность 3D demo на главной странице.
## Проблема
Товар выглядел так, будто "летит" выше конвейера:
- `beltY` был 0.35м вместо 0.7м
- `itemOffsetY` добавлял ещё смещение
- Итоговая высота товара: 0.5м — неправильно
- Конвейер не имел реалистичной структуры (без опор до пола)
## Root Cause
В `conveyorPath.ts` были hardcoded значения:
```typescript
beltY: 0.35, // Должно быть 0.7м
itemOffsetY: 0.15, // Добавлялось без учёта размера товара
```
В `SorterDigitalTwinContinuous.tsx` belt surface был на 0.32м.
## Решение
### 1. Создан единый файл размеров
`src/domain/physicalLayout.ts` — единый источник правды:
| Параметр | Значение | Описание |
|----------|----------|----------|
| `CONVEYOR_WIDTH_M` | 0.5м | Ширина полотна |
| `CONVEYOR_HEIGHT_M` | 0.7м | Высота верха полотна |
| `CONVEYOR_SPEED_MPS` | 1.0 м/с | Скорость ленты |
| `BELT_THICKNESS_M` | 0.015м | Толщина полотна |
| `ROLLER_RADIUS_M` | 0.04м | Радиус ролика |
| `ROLLER_SPACING_M` | 0.15м | Шаг роликов |
### 2. Формула высоты товара
```typescript
// Товар сидит НА ленте: верх полотна + половина высоты товара
itemY = BELT_TOP_Y + itemVisualHeight / 2
// BELT_TOP_Y = 0.7м
```
### 3. Реалистичный конвейер
Добавлены компоненты:
- **Belt surface** — верхняя рабочая поверхность на 0.7м
- **Side guards** — боковые направляющие выше полотна
- **Frame rails** — рама под полотном
- **Rollers** — вращающиеся ролики под лентой
- **Drive roller** — приводной ролик (увеличенный)
- **Tension roller** — натяжной ролик
- **Support legs** — опоры от пола до рамы
- **Stepper motor** — шаговый двигатель у приводного ролика
### 4. Позиции зон
```typescript
ZONES = {
A: { x: -4.0, z: 0 }, // Spawn
CAMERA: { x: -1.5, z: 0 }, // Detection
GATE: { x: 1.5, z: 0 }, // Diverter
B: { x: 4.0, z: 0 }, // Main exit
C: { x: 2.0, z: 2.0 }, // Oversized
D: { x: 2.0, z: -2.0 }, // Round
}
```
## Файлы изменены
| Файл | Изменения |
|------|-----------|
| `src/domain/physicalLayout.ts` | **Создан** — все физические размеры |
| `src/domain/conveyorPath.ts` | Импорт из physicalLayout, правильный расчёт itemY |
| `src/components/ThreeD/SorterDigitalTwinContinuous.tsx` | Новый ConveyorBelt с правильными размерами |
## Скриншоты
`docs/physical_conveyor_screenshots/`:
- `conveyor_side_view.png` — боковой вид с опорами
- `item_on_belt.png` — товар на полотне
- `running_item_on_belt.png` — товар движется
- `motor_drive.png` — виден stepper motor
- `conveyor_top_angle.png` — вид сверху
- `details_page.png` — /details не сломан
## Проверки
| Проверка | Результат |
|----------|-----------|
| `npm run build` | ✅ Успешно |
| `npm run test` | ✅ 59 тестов |
| Docker rebuild | ✅ Успешно |
| Production QA | ✅ Работает |
| Console errors | ✅ Нет ошибок |
## Что осталось
- Визуально stepper motor небольшой — это правильно для масштаба
- Можно добавить более детальную геометрию роликов (низкий приоритет)
- Roll-cages для C/D зон можно добавить отдельно
## Команды для commit/push
```bash
git add -A
git commit -m "fix: physical conveyor realism - belt at 0.7m, item rides ON belt
- Create physicalLayout.ts with all dimensions
- Update conveyorPath.ts to use correct belt height
- Rebuild ConveyorBelt with proper structure:
- Support legs from floor
- Rollers under belt
- Drive/tension rollers
- Stepper motor at drive end
- Item Y = BELT_TOP_Y + itemHeight/2
Closes: item floating above conveyor"
git push origin dan_branch
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB