primitive meshes

This commit is contained in:
Jérôme Bousquié
2026-09-24 14:25:44 +02:00
parent 805babe53d
commit ab3f056dbb
36 changed files with 1531 additions and 808 deletions
+89 -32
View File
@@ -1,42 +1,99 @@
# DRAFT — Étape 20 : HDR + Tone Mapping ✅
# Étape 21 — Module `mesh` : primitives optionnelles + import
> **STATUT : TERMINÉ** — implémenté et testé.
> Ce document sera remplacé par le prochain draft.
**Statut : ✅ TERMINÉE**
## Récapitulatif
## Résumé
- [x] **20.1** — Shader TM (`tonemap.wgsl`) : fullscreen triangle + 2 curves (ACES/Reinhard) + validation naga ✅
- [x] **20.2** — `ToneMapper` enum (`core/hdr.rs`) : dispatch compile-time ✅
- [x] **20.3** — `AppBuilder::with_hdr(ToneMapper)` + plomberie App → AppRunner → Renderer ✅
- [x] **20.4** — Allocation HDR (`Rgba16Float` offscreen) dans `Renderer::new` ✅
- [x] **20.5** — Main pass conditionnel (cible HDR vs surface) ✅
- [x] **20.6** — Passe TM (fullscreen triangle → surface sRGB) ✅
- [x] **20.7** — Resize : recreation texture HDR + bind group ✅
- [x] **20.8** — Démo HDR + documentation (`docs/user/hdr.md`) ✅
Restructuration du module de géométrie :
- `math/` supprimé — types (`Geometry`, `Transform`, `BBox`, `Frustum`, LOD) déplacés vers `core/`
- `primitives.rs` (monolith) → `mesh/primitives/` (6 fichiers, un par famille)
- Nouveau module `wsg::mesh` : point d'entrée unique pour les sources de géométrie
- Features par primitive (`prim-cube`, `prim-sphere`, …) — zéro coût si désactivées
- Parser OBJ intégré (zéro dep externe), wrapper glTF en stub
- `prelude.rs` pour un glob import confortable
- Re-exports top-level : `Geometry`, `Transform`, `BBox`
## Fichiers modifiés/créés
## Structure finale
| Fichier | Action |
|---------|--------|
| `lib/src/shaders/tonemap.wgsl` | **Nouveau** — fullscreen triangle + fs_aces + fs_reinhard |
| `lib/src/core/hdr.rs` | **Nouveau** — `ToneMapper` enum |
| `lib/src/core/mod.rs` | + `pub mod hdr` + re-export |
| `lib/src/core/renderer.rs` | + `HdrPipeline` struct, + HDR alloc, + TM pass, + resize, + helpers |
| `lib/src/utils/conf.rs` | + `TONEMAP_SHADER` constant |
| `lib/src/app.rs` | + `with_hdr()`, + `hdr` field plomberie |
| `lib/src/lib.rs` | + `pub use ToneMapper` |
| `lib/examples/demo.rs` | + `.with_hdr(ToneMapper::Aces)` |
| `lib/examples/manual.rs` | + `None` param (backward compat) |
| `lib/tests/wgsl_validate.rs` | + test tonemap |
| `docs/user/hdr.md` | **Nouveau** — doc utilisateur |
| `docs/user/README.md` | + lien HDR |
```
lib/src/
├── lib.rs # + pub mod mesh, pub mod prelude, re-exports Geometry/Transform/BBox
├── prelude.rs # glob re-exports (types quotidiens)
├── core/
│ ├── mod.rs # + geometry, transform, frustum, lod
│ ├── geometry.rs # ← déplacé de math/
│ ├── transform.rs # ← déplacé de math/
│ ├── frustum.rs # ← déplacé de math/
│ ├── lod.rs # ← déplacé de math/
│ ├── renderer.rs
│ ├── shadow.rs
│ ├── hdr.rs
│ ├── context.rs
│ ├── frame.rs
│ └── input.rs
├── mesh/
│ ├── mod.rs # re-exports flat (cube, plane, sphere, …, load_obj, …)
│ ├── primitives/
│ │ ├── mod.rs
│ │ ├── cube.rs
│ │ ├── plane.rs
│ │ ├── sphere.rs # uv_sphere + icosphere
│ │ ├── cylinder.rs
│ │ ├── cone.rs
│ │ └── torus.rs
│ └── import/
│ ├── mod.rs # MeshImportError
│ ├── obj.rs # parser OBJ (zéro dep)
│ └── gltf.rs # stub (wrapper gltf crate à implémenter)
├── app.rs
├── handler.rs
├── pipeline/
├── resources/
├── scene/
└── utils/
```
## Features (Cargo.toml)
| Feature | Default | Fournit |
|---------|---------|---------|
| `prim-cube` | ✅ (via all-prims) | `cube(size)` |
| `prim-plane` | ✅ | `plane(w, d, sx, sz)` |
| `prim-sphere` | ✅ | `uv_sphere(…)`, `icosphere(…)` |
| `prim-cylinder` | ✅ | `cylinder(…)` |
| `prim-cone` | ✅ | `cone(…)` |
| `prim-torus` | ✅ | `torus(…)` |
| `all-prims` | ✅ (default) | les 6 ci-dessus |
| `import-obj` | ⬜ | `load_obj(path)`, `parse_obj(str)` |
| `import-gltf` | ⬜ | `load_gltf(path)` (stub) |
## Décisions
| # | Décision |
|---|----------|
| D1 | Un seul crate `wsg-lib` — pas de crate séparée |
| D2 | Feature par famille de primitives |
| D3 | Feature par format d'import |
| D4 | Pas de trait `MeshSource` — fonctions qui retournent `Geometry` |
| D5 | `Geometry::new()` / `Scene::add_mesh()` restent en core |
| D6 | Module `wsg::mesh` au même niveau que `core`, `app` |
| D7 | `primitives/` un fichier par famille |
| D8 | `import/` un fichier par format |
| D9 | Import retourne `Result<_, MeshImportError>` |
| D10 | `default = ["all-prims"]` |
| D11 | `all-prims` = les 6 primitives |
| D12 | `math` disparaît — types re-exportés par `core` / top-level |
## Tests
- 99 unit tests ✅
- 4 WGSL validation (dont `tonemap_shader_is_valid_wgsl`) ✅
- 3 doctests ✅
- 107 unit tests (dont 7 tests OBJ parser)
- 4 WGSL validation
- 5 doctests
- **Total : 116 tests, 0 failures**
## Prochaine étape
## Build vérifié
Phase 4 complète (4.1 + 4.2 + 4.3 + HDR/TM). Le ROADMAP peut être mis à jour.
- `cargo check` (default = all-prims) ✅
- `cargo check --no-default-features --features "prim-cube"` ✅
- `cargo check --features "import-obj,import-gltf"` ✅
- `cargo check --examples --features "import-obj"` ✅