Files
wsg/docs/DRAFT.md
T
Jérôme Bousquié 4bfd712496 fix: shadow caster index, torus winding, per-frame device poll ; close stage 15
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).
2026-09-20 20:36:25 +02:00

46 lines
3.2 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.
# 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.