4bfd712496
Bug fixes found while validating stage 15: - demo: set_shadow_caster(Some(0)) selected the default +Z light (packed index 0 from Lights::new()); the demo's warm directional light is packed at index 1. The shadow camera then looked down -Z, so misaligned objects occluded each other (cone/torus rendered black). Use index 1. - primitives::torus: index winding was flipped ([a,c,b]); the outer surface (outward normals, CCW from outside) was culled and only the dark interior stayed visible. Reversed to [a,b,c]/[b,d,c] so it is CCW from outside. - app: call device.poll() each frame in about_to_wait; without it wgpu async callbacks (on_submitted_work_done, map_async) never fire in the windowed loop. Docs: - conf: clarify the embedded-shader fallback is expected/harmless and that SHADOW_SHADER_PATH is kept for API compatibility only. - README item 15: runtime-verified headless. - DRAFT.md: emptied to a completion summary per convention (full stage-15 plan preserved in git history).
46 lines
3.2 KiB
Markdown
46 lines
3.2 KiB
Markdown
# DRAFT — Étape suivante
|
||
|
||
> 📅 **Étape 15 — TERMINÉE (2026-09-20).** Document vidé conformément à la convention
|
||
> (« ce document est vidé à la complétion de chaque étape »). Le plan détaillé (objectifs,
|
||
> décisions D1–D9, détail d'implémentation, périmètre) est archivé dans l'historique git du
|
||
> présent fichier — `git log -- docs/DRAFT.md`.
|
||
|
||
## Bilan de l'Étape 15 (archive)
|
||
|
||
**Objectif atteint** : un démonstrateur `demo` interactif cumulant les étapes 8-14 — un sol texturé
|
||
damier + 6 primitives (cube, sphère UV, icosphère, cylindre, cône, tore) texturées, éclairées
|
||
(multi-lumières + spot, Étapes 12-13), projetant des **ombres** (Étape 14), et pilotées par une
|
||
**caméra orbitale** au clavier/souris (glisser = orbite, molette = zoom, `R` = reset, `1`/`2`/`3` =
|
||
présettes) via un nouveau **module d'input unifié** — le tout dans le workflow déclaratif
|
||
`AppBuilder` + `AppHandler`, sans importer wgpu.
|
||
|
||
**Trois volets livrés :**
|
||
- **15.A — `math::primitives`** : générateurs de `Geometry` prêts à l'emploi (`cube`, `plane`,
|
||
`uv_sphere`, `icosphere`, `cylinder`, `cone`, `torus`) + 6 tests. Le `cube_geometry` des exemples
|
||
(`cube.rs`, `spot_test.rs`) a été factorisé vers `math::cube(1.0)`.
|
||
- **15.B — `core::input`** : `InputState` unifié (clavier `KeyCode` / souris position+delta+molette,
|
||
sémantique pressed/held/released) branché dans `App` (`app.input` public, rotation
|
||
`begin_frame`/`end_frame` autour de `update`) + 5 tests. Gamepad **reporté** (D7) — champ réservé.
|
||
- **15.C — `demo` + caméra orbitale** : `resources::CameraController` (yaw/pitch/distance/target,
|
||
`apply_to`) + exemple `demo` (sol + 6 primitives + lumières + ombres + caméra orbitale).
|
||
|
||
**Livraison** : ROADMAP 2.2 (primitifs) et 2.3 (input) cochées (gamepad `[~]` partiel) ; README items
|
||
13-15 ajoutés ; `cargo fmt --all -- --check` propre ; build workspace + exemples ; 28 tests unitaires
|
||
+ doctests au vert ; `demo` vérifié au runtime (headless).
|
||
|
||
**Corrections de bugs découvertes en cours de route :**
|
||
- *Ombres du `demo`* : `set_shadow_caster(Some(0))` désignait la lumière directionnelle **+Z par
|
||
défaut** préchargée par `Lights::new()` (index 0 packé) au lieu de la lumière chaude du demo
|
||
(index 1) → la caméra d'ombre regardait −Z et des objets non-alignés s'occluaient mutuellement
|
||
(tore/cône noircis). Corrigé en `Some(1)`.
|
||
- *Tore noir* : le winding du tore (`primitives::torus`) était inversé (`[a, c, b]`), la face externe
|
||
était cullée et seul l'intérieur (normales vers l'extérieur → N·L ≤ 0) restait visible. Corrigé en
|
||
`[a, b, c]` + `[b, d, c]` (CCW vu de l'extérieur).
|
||
- *`App::run`* : ajout d'un `device.poll()` par frame — sans lui, les callbacks asynchrones wgpu
|
||
(`on_submitted_work_done`, `map_async`) ne firent jamais dans la boucle de production.
|
||
- *Docs* : `STANDARD_SHADER_PATH` pointait vers un fichier absent (le vrai shader est embarqué via
|
||
`include_str!`) ; le fallback est attendu et inoffensif — doc corrigée.
|
||
|
||
**Hors périmètre (reporté)** : `set_active_camera` multi-caméras (2.1), `InputUniforms` WGSL
|
||
(debug/gizmo), GPU-driven (Phase 3), batching matériau (4.3), LOD, HDR/tone mapping, gamepad complet.
|