- D2 : Geometry reste en math (structure de donnees pure), re-export racine
- D4 : voie unique Mesh::from_geometry(Arc<Geometry>) ; suppression de l API &[Vertex]
- D5 : retention CPU (Arc<Geometry>) + buffers GPU pre-uploades
- D6 : convertisseur nomme Geometry::to_vertices() avec regles de remplissage
Toutes les decisions D1-D6 et la proposition 8.1 sont desormais validees.
- Camera enrichie: fov/near/far stockés, Default (pos (0,0,3), 45°, near 0.1,
far 100), with_perspective(), projection_matrix(aspect) depuis les params
stockés (au lieu de les passer en argument).
- Scene porte une caméra active: set_camera()/camera() (défaut Camera::default).
- Renderer::render_scene(view, scene, aspect) écrit chaque frame view/proj/
cam_pos réels dans le buffer frame (write_frame_uniforms) avant de dessiner;
le Renderer garde le handle du frame_buffer. Le chemin bas-niveau render()
conserve les valeurs par défaut (identité).
- App::render_scene calcule l'aspect depuis window.inner_size() (le Renderer
reste indépendant de la fenêtre).
Docs synchronisées: DRAFT (4.3 coche), README (statut 3D-infra + quick ref),
PLAN (caméras), ROADMAP (1.1/1.3/1.5/2.3).
Validation: check workspace+examples 0 warning, test (Pod + wgsl) OK, doc 0
warning, fmt propre. Le rendu 3D visible attend Étape 5 (brancher standard).
Étape 3 (infrastructure uniforms) + le câblage minimal d'Étape 4 pour garder
les exemples exécutables (wgpu requiert que tous les bind groups du layout
pipeline soient posés au draw) :
- resources/uniform.rs : types bytemuck Pod FrameUniforms (192 B) et
ObjectUniform (64 B), alignés 16 octets sans padding; offsets vérifiés par un
test unitaire contre le contrat du shader. glam feature bytemuck activé.
- pipeline_cache: create_uniform_bind_group_layouts() expose les 2 layouts
(frame @0 Vertex|Fragment + object @1 Vertex); build_pipeline les attache à
TOUT pipeline (un seul layout pour tous, décision actée).
- Renderer: alloue le buffer frame partagé + BindGroup(0) (défaut identité,
mode lit) et un object identité partagé pour le chemin bas-niveau; cache
RefCell<HashMap<label,(buffer,bindgroup)>> par entité, model réécrit chaque
frame depuis transform.to_matrix(); draw_entity pose groupes 0+1.
4.3 (caméra active + aspect) non implémenté: simple/manual restent exécutables
car basic ignore ces uniforms. Documentation DRAFT mise à jour.
Validation: check workspace+examples 0 warning, doc 0 warning, test (Pod+wgsl)
OK, fmt propre.
Étape 2 du plan 3D+Phong : nouveau shader unifié, non encore branché à un
pipeline (Étape 3 : infra uniforms).
- shaders/standard_shader.wgsl : contrat vertex complet (position/normal/uv/color,
56 octets, corrige la défaut latente du basic) ; 2 bind groups formative frame
(view/proj/cam_pos/light_dir/light_color/options) + object (model) ; éclairage
hemisphérique ambient + diffuse directionnel; mode unlit (options.x) pour que la
2D plate soit un cas partticulier de la 3D.
- utils/conf.rs : constantes STANDARD_SHADER_PATH + STANDARD_SHADER (include_str!).
- tests/wgsl_validate.rs : validation hors-ligne naga (via wgpu::naga, aucune
nouvelle dépendance) tant que le shader n'est pas compilé par un pipeline.
- shaders/README.md : documente le contrat standard et le statut du basic.
- Erreur WGSL corrigée en validation: cast mat4x4->mat3x3 non supporte, remplacé
par construction explicite de la sous-matrice 3x3.
- Validation: cargo test (naga OK), check workspace+examples 0 warning, doc OK, fmt OK.
Étape 1 du plan 3D+Phong : fondations de données sans toucher au rendu.
- resources: exporte Camera (fichier auparavant orphelin), migre les fonctions
glam dépréciées look_at_rh/perspective_rh_gl vers glam::camera::rh::* (induit
par la compilation de camera.rs, sinon 2 warnings).
- scene: nouveau type Entity { mesh_id, material_id, transform } (scene/entity.rs);
Scene::entities passe de HashMap<String,(String,String)> à HashMap<String,Entity>.
- API: add_entity conserve sa signature (transform identité par défaut), ajout de
add_entity_with_transform, entity_transform, set_entity_transform; iter_entities
rend désormais aussi le &Transform. renderer et examples inchangés a posteriori.
- Validation: cargo check --workspace et examples 0 warning, cargo doc 0 warning, fmt OK.
DRAFT.md now lives in docs/. Confirmed the pending design decisions:
render() auto-renders the scene by default (Option A, alternative B removed),
and simple.rs uses app.renderer.device()/format() via the library API
without importing wgpu.