Files
wsg/docs/PLAN.md
T
Jérôme Bousquié acf819737d docs: purge PLAN/ROADMAP des plans abandonnés, DRAFT vidé (Étape 10 finie)
La documentation reflète désormais uniquement ce qui *est* et ce qu'on
envisage de faire, pas ce qui aurait pu être (changements d'avis retirés) :

ROADMAP.md
- 1.2 : remplacé le récit de décision 'transform sur Mesh' (DRAFT Étape 8,
  déviation) par l'énoncé de l'état actuel : Mesh porte son matériau + sa
  Geometry CPU partagée, pas de transform (porté par Entity).
- Phase 2 réécrite : suppression des 'Arènes complètes' (SlotMap) et de la
  struct Entity { mesh_id, material_id } contredite par l'Étape 7 (material
  déplacé sur Mesh) et le choix String IDs ; migration 'handles typés'
  conservée comme unique pointeur (1.4 / Notes de Décision).
- 4.2 : 'Lumières hémisphériques' cochée (déjà dans standard_shader).
- Notes de Décision : retiré 'UVs en Phase 4' (caduque, UVs implémentés dès
  Geometry).

PLAN.md
- Statut réel condensé et mis à jour jusqu'à l'Étape 10 (textures).
- Phase 4 : Textures cochée (faite), Lumières laissée en plan (ROADMAP 4.2).
- Check-list pollster dé-obsolétisée ; suppression de la 'Note pour mémoire'
  décrivant le module-pivot exec.rs qu'on a décidé de ne pas construire.

DRAFT.md
- Vidé (fin de l'Étape 10) en préparation de l'étape suivante.
2026-09-18 15:01:27 +02:00

100 lines
7.0 KiB
Markdown

---
type: Plan
title: Implementation Plan for wsg_lib Engine Consolidation and Finalization
description: Implementation plan defining priority steps to finalize the current architecture, making the API intuitive for standard users while maintaining power for advanced users
tags: [plan, implementation, roadmap, development, wsg-lib]
status: stable
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
---
# Plan d'Implémentation : Consolidation et Finalisation du Moteur wsg_lib
Ce plan définit les étapes prioritaires pour finaliser l'architecture actuelle. L'objectif est de rendre l'API intuitive pour l'utilisateur standard tout en conservant la puissance de contrôle pour l'utilisateur avancé.
> **Statut réel (à jour au 2026-09-18).** La phase de *consolidation* (Phases 1 à 3 de ce plan) est
> **terminée** ; la source de vérité sur l'état actuel est **README.md** et le code. Depuis la révision
> du 2026-09-14, le rendu de la `Scene` est automatisé en une passe groupée
> (`App::render_scene(frame.view())`, appelée par défaut dans `AppHandler::render`) et `simple.rs`
> (API `AppBuilder`, sans `winit`/`wgpu`) déclare un quad rendu automatiquement. Les étapes suivantes
> ont ensuite : posé l'infrastructure 3D (bind groups uniformes frame+object partagés, caméra active,
> matrices monde par entité — Étapes 3+4, 2026-09-16) ; atteint le **MVP 3D Phong** (Étape 5,
> 2026-09-17 : l'exemple `cube` ; le 2D plat = variante **unlit** de `standard` via
> `Renderer::set_unlit`) ; rattaché le `PipelineCache` à la `Scene` et fait référencer son `Material`
> par chaque `Mesh` (Étape 7) ; donné à `Mesh` une source de vérité **CPU partagée**
> (`geometry: Arc<Geometry>`, Étape 8) ; activé un **depth buffer** sur toutes les passes (Étape 9) ;
> et ajouté les **textures diffuses** (Étape 10, 2026-09-18 : `resources::Texture` + bind group @2 +
> `Material.texture`).
## Phase 1 : Finalisation et Nettoyage de l'Existant (Priorité Absolue)
Cette phase vise à supprimer la dette technique et à unifier les accès.
### Uniformisation des Modules
- [X] Vérifier que tous les traits (`AppHandler`) et structures (`App`, `Context`) sont explicitement marqués `pub` dans leurs fichiers sources.
- [X] Ré-exporter l'API dans `lib.rs` pour permettre des imports simplifiés (ex : `use wsg_lib::{App, AppHandler}`).
- [X] Nettoyer les accès internes pour que l'utilisateur n'ait pas à importer les modules système (`core`, `pipeline`) sauf besoin spécifique.
### Abstraction de la Boucle (`App::run`)
- [X] Déplacer la gestion de `winit::event_loop` et des `Frame` à l'intérieur de la méthode `run()` de `App`.
- [X] Garantir que le trait `AppHandler` reçoit une référence à `App` permettant d'appeler `app.renderer` ou `app.scene`.
- [X] Supprimer toute gestion de `Frame` ou `EventLoop` manuelle des exemples utilisateurs (`simple.rs`).
### Correction du Builder et Initialisation
- [X] Standardiser la création de `App` via un `AppBuilder` robuste.
- [X] Gérer les `dev-dependencies` dans `lib/Cargo.toml` (notamment `pollster` avec la feature `macro`) pour permettre la compilation des exemples sans polluer les dépendances finales de la librairie.
## Phase 2 : Structure de Rendu et Scène
Une fois la plomberie encapsulée, nous devons rendre l'assemblage des objets cohérent.
### Intégration de la Scene
- [X] Formaliser la structure `Scene` : un conteneur qui liste les Entities.
- [X] Associer le `PipelineCache` à la Scene pour que la gestion des matériaux soit entièrement portée par la scène (actuellement le cache est porté par `App`, indépendant de la Scene — le rendu de la scène est, lui, déjà automatisé depuis 2026-09-16). *(fait — 2026-09-17, DRAFT Étape 7 : `Scene::init_gpu` détient device+format+`PipelineCache` ; `App` n'a plus de champ `cache`)*
- [X] Implémenter la logique de rendu de la scène : `App::render_scene(view)` parcourt la scène,
récupère les matériaux et soumet tous les draw calls en **une seule passe groupée**
(`Renderer::render_scene`), appelée automatiquement chaque frame par l'implémentation par défaut
de `AppHandler::render` (Scene auto-render — réalisé 2026-09-16). Reste à brancher : associé au
`PipelineCache` porté par la `Scene` (cf. ligne précédente).
### Gestion des Matériaux et Shaders
- [X] S'assurer que chaque Mesh possède une référence vers un Material (à l'heure actuelle le lien est porté par l'entité `(mesh_id, material_id)` de la Scene, pas par le Mesh lui-même). *(fait — 2026-09-17, DRAFT Étape 7 : `Mesh.material: Option<Arc<Material>>` ; `Entity { mesh_id, transform }`, plus de `material_id`)*
- [X] Implémenter le comportement par défaut : si aucun matériau n'est assigné, le moteur injecte automatiquement le `standard_shader` (variante unlit) (non implémenté). *(fait — 2026-09-17, DRAFT Étape 7.3.5 : `Scene::default_material()` injecte `standard` ; le flat reste piloté par `Renderer::set_unlit`)*
## Phase 3 : Documentation et Interface (API "User-Friendly")
### Refonte des Exemples
- [X] `simple.rs` doit devenir le modèle : **15 lignes** de code, pas de manipulation WGPU explicite (mis en conformité : `AppBuilder`, compile sans `winit`/`wgpu`).
- [X] `manual.rs` doit rester disponible en tant que tutoriel pour ceux qui veulent contourner l'abstraction App.
### Nettoyage du Code Interne
- [X] Vérifier les durées de vie (lifetimes) et les Arc pour s'assurer qu'aucune fuite mémoire ou accès concurrentiel invalide ne survient lors des changements de frame.
## Phase 4 : Nouvelles Fonctionnalités (Planification Future)
Une fois les phases 1 à 3 validées, nous pourrons introduire :
- [ ] **Système de Lumières** : Ajout de buffers d'uniformes dans le PipelineCache *(planifié — ROADMAP 4.2, Éclairage avancé)*.
- [X] **Textures** : Intégration d'un module de chargement d'images et de BindGroups *(fait 2026-09-18,
Étape 10, ROADMAP 4.1 : `resources::Texture`, bind group @2, `Material.texture`)*.
- [X] **Caméras** : Gestion des matrices de projection/vue dans la Scene *(fait 2026-09-16, Étape 4.3 —
`Scene::set_camera`/`camera()` porte une caméra active ; `render_scene` écrit view/proj/cam_pos réels
dans le buffer frame chaque frame, aspect calculé depuis la fenêtre)*.
## Check-list de Vérification pour le LLM d'Assistance
- [X] Est-ce que `simple.rs` compile sans importer `winit` ou `wgpu` ? (oui — modèle 15 lignes, API `AppBuilder`)
- [X] Est-ce que `App::run` gère bien le cycle update → render → present ? (oui — la vue de frame est
exposée via `Frame::view()`, `render()` dessine la scène automatiquement en une passe via
`App::render_scene(frame.view())`, la présentation est faite par `App::run`)
- [X] Les modules sont-ils bien exposés via `lib.rs` ?
- [X] `pollster` est-il isolé de l'utilisateur final ? — résolu : depuis winit 0.30 (2026-09-16),
`pollster` est en `dependencies` de la lib ; le `block_on` de l'init GPU est appelé une seule fois
dans `lib/src/app.rs` (`resumed()`). Les exemples compilent sans le connaître (crates séparées).