Compare commits

..

4 Commits

Author SHA1 Message Date
Jérôme Bousquié e8e9124a9d doc : single buffer 2026-08-03 21:52:36 +02:00
Jérôme Bousquié 895965750f préparation phase 1.1 2026-08-01 21:25:43 +02:00
Jérôme Bousquié 37432536dc refactor spec OKF 2026-08-01 09:34:12 +02:00
Jérôme Bousquié 81b825970a correction contradictions 2026-07-31 20:43:57 +02:00
30 changed files with 854 additions and 36 deletions
View File
Generated
+8
View File
@@ -501,6 +501,12 @@ dependencies = [
"xml-rs", "xml-rs",
] ]
[[package]]
name = "glam"
version = "0.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f22fb22f065b308be0d8724e3706c7fa3fc2a6c7d6899df4cad7860e7a75436"
[[package]] [[package]]
name = "glow" name = "glow"
version = "0.17.0" version = "0.17.0"
@@ -2323,7 +2329,9 @@ name = "wsg-lib"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"glam",
"pollster", "pollster",
"slotmap",
"thiserror 2.0.18", "thiserror 2.0.18",
"wgpu", "wgpu",
"winit", "winit",
+3 -3
View File
@@ -19,16 +19,16 @@ generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
**Objectif** : Afficher un cube (ou autre mesh) 3D avec un éclairage Phong basique. **Objectif** : Afficher un cube (ou autre mesh) 3D avec un éclairage Phong basique.
### 1.1 Dépendances & Mathématiques ### 1.1 Dépendances & Mathématiques
- [ ] Ajouter `glam = "0.29"` en dépendance (`lib/Cargo.toml`) - [ ] Ajouter `glam = "0.33"` en dépendance (`lib/Cargo.toml`)
- [ ] Ajouter `slotmap = "1.0"` en dépendance - [ ] Ajouter `slotmap = "1.0"` en dépendance
- [ ] Créer module `math/` (ou `transform.rs`) : - [ ] Créer module `math/` (ou `transform.rs`) :
- [ ] Struct `Transform { translation: Vec3, rotation: Quat, scale: Vec3 }` - [ ] Struct `Transform { translation: Vec3, rotation: Quat, scale: Vec3 }`
- [ ] Méthode `to_matrix() -> Mat4` pour calculer la matrice locale - [ ] Méthode `to_matrix() -> Mat4` pour calculer la matrice locale
- [ ] Struct `Camera { position: Vec3, target: Vec3, up: Vec3 }` - [ ] Struct `Camera { position: Vec3, target: Vec3, up: Vec3 }` : resources/camera.rs
- [ ] Fonctions `view_matrix()` et `projection_matrix(fov, aspect, near, far)` - [ ] Fonctions `view_matrix()` et `projection_matrix(fov, aspect, near, far)`
### 1.2 Geometry & Mesh ### 1.2 Geometry & Mesh
- [ ] Créer struct `Geometry` : - [ ] Créer struct `Geometry` (math/geometry.rs) :
- [ ] `positions: Vec<[f32; 3]>` (obligatoire) - [ ] `positions: Vec<[f32; 3]>` (obligatoire)
- [ ] `indices: Option<Vec<u16>>` (optionnel) - [ ] `indices: Option<Vec<u16>>` (optionnel)
- [ ] `normals: Option<Vec<[f32; 3]>>` (pour Phong) - [ ] `normals: Option<Vec<[f32; 3]>>` (pour Phong)
+22 -10
View File
@@ -1,24 +1,36 @@
--- ---
type: Reference type: Rule
title: IAgent Documentation Rules title: Documentation Rules
description: Rules and guidelines for documentation in the IAgent project, following OKF v0.2 specification description: Rules and guidelines for documentation in the WSG project, following OKF v0.2 specification
resource: https://github.com/wsg-project/wsg/blob/main/docs/rules/DOCUMENTATION.md
tags: [documentation, guidelines, standards] tags: [documentation, guidelines, standards]
status: stable sources: [{ ref: SPEC.md }]
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } verified: { by: "human:jerome", at: 2026-07-31T00:00:00Z }
status: active
stale_after: 2027-01-31T00:00:00Z
generated: { by: "human:jerome", at: 2026-07-31T00:00:00Z }
--- ---
# IAgent Documentation Rules # Documentation Rules
## Language ## Schema
All documentation follows the OKF v0.2 specification (see [SPEC.md](https://github.com/wsg-project/wsg/blob/main/docs/rules/SPEC.md)). This document defines project-specific rules for writing and maintaining code documentation.
## Conventions
### Language
All documentation is written in English; as a convention, the code itself uses English for variable names, function names, etc. All documentation is written in English; as a convention, the code itself uses English for variable names, function names, etc.
## Code Documentation ### Code Documentation
Every source file and configuration file must be systematically documented following the rules defined in this DOCUMENTATION.md file. Additionally, every directory must contain its own README.md file summarizing and explaining the module's organization at that level: what is the overall responsibility of the files grouped in this directory, which ones they are, and what each one does. Every source file and configuration file must be systematically documented following the rules defined in this DOCUMENTATION.md file. Additionally, every directory must contain its own README.md file summarizing and explaining the module's organization at that level: what is the overall responsibility of the files grouped in this directory, which ones they are, and what each one does.
We assume the reader has professional algorithmic knowledge but may not necessarily be a Rust specialist. The reader does know the project's domain — LLM logic, clients, and agents. Documentation should therefore be tailored for a professional developer who knows some programming languages (not necessarily Rust). We assume the reader has professional algorithmic knowledge but may not necessarily be a Rust specialist. The reader does know the project's domain — LLM logic, clients, and agents. Documentation should therefore be tailored for a professional developer who knows some programming languages (not necessarily Rust).
## Examples
### General Rule ### General Rule
Documentation must describe what is coded and what purpose it serves. A LLM reading the code and documentation should be able to verify whether: Documentation must describe what is coded and what purpose it serves. A LLM reading the code and documentation should be able to verify whether:
@@ -29,7 +41,7 @@ Documentation must describe what is coded and what purpose it serves. A LLM read
Each module or file must include documentation explaining the module's responsibility and how it interacts with other modules in the program, at least those within its own directory. This documentation must detail the main objects (Struct, Enum, Trait) manipulated in the module and the primary functions that carry the module's core logic. Each module or file must include documentation explaining the module's responsibility and how it interacts with other modules in the program, at least those within its own directory. This documentation must detail the main objects (Struct, Enum, Trait) manipulated in the module and the primary functions that carry the module's core logic.
## Within a File's Code ## Internal Steps
### Object and Function Headers ### Object and Function Headers
@@ -39,6 +51,6 @@ At the header of each object, describe what the object represents and its purpos
If an object or function presents a particularity or specific technical point, then a descriptive comment is inserted directly into the code body or function body. If a point of attention or technical point was described in the function header, then a comment in the code body reminds where this point is located. If an object or function presents a particularity or specific technical point, then a descriptive comment is inserted directly into the code body or function body. If a point of attention or technical point was described in the function header, then a comment in the code body reminds where this point is located.
## Documentation Maintenance ## Maintenance
The rules defined in this file are regularly applied across all code documentation to ensure consistency between code evolution and its documentation. The rules defined in this file are regularly applied across all code documentation to ensure consistency between code evolution and its documentation.
+54
View File
@@ -0,0 +1,54 @@
---
type: Specification
title: Open Knowledge Framework (OKF) v0.2 Specification
sources: [SPEC.md]
generated: true
verified: false
status: draft
stale_after: 2026-12-31
---
# Open Knowledge Framework v0.2 Summary
This document provides a concise overview of the OKF v0.2 specification as implemented in the WSG project. It aggregates the key concepts defined in the fragment files under `docs/rules/fragments/`.
## 1. Crosslinking and Paths (Fragment05)
- Local bundle links use the `@/` prefix.
- Paths are written without the `.md` extension.
- Enables a graph of interconcept relationships.
## 2. Provenance `sources` (Fragment06)
- `sources` records origin identifiers (files, URLs).
- Supports traceability and impact analysis.
## 3. Trust `generated` / `verified` (Fragment07)
- `generated: true` for automatically produced docs.
- `verified: true` only after human review.
## 4. Lifecycle `status` & `stale_after` (Fragment08)
- `status` values: `draft`, `current`, `deprecated`, `archived`.
- `stale_after` ISO8601 date triggers review.
## 5. Actor Convention (Fragment09)
- `actor` field follows `<type>/<name>` (e.g., `person/jdoe`).
- Provides attribution and accountability.
## 6. Attested Computation (§10) (Fragment10)
- `computation` describes a deterministic script and its arguments.
- Successful run allows promotion to `verified: true`.
## 7. Index Files (Fragment11)
- `index.md` lists bundle concepts for humans and tools.
- Must stay synchronized with actual content.
## 8. Log Files (Fragment12)
- `log.md` records timestamped, actoridentified changes.
- Enables audit trails and diff generation.
## 9. Changes from v0.1 (Fragment13)
- Introduced `stale_after`, `actor`, `computation` fields.
- Standardised boolean flags and crosslink syntax.
---
*All fragment files are stored under `docs/rules/fragments/` and should be kept in sync with this summary. Future revisions of the specification will update the `status` and `stale_after` fields accordingly.*
+21
View File
@@ -0,0 +1,21 @@
---
type: Section
title: Motivation
---
# Motivation
The space of knowledge representation for AI agents is evolving quickly, and many incompatible conventions are emerging. OKF takes the position that knowledge is best represented in commonly accessible, established formats that are:
- **Readable** by humans without tooling.
- **Parseable** by agents without bespoke SDKs.
- **Diffable** in version control.
- **Portable** across tools, organizations, and time.
Increasingly, a knowledge corpus is not authored once and then read: it is **continuously written and maintained by agents**. When most concepts are machinegenerated, a consumer needs answers that a plain markdownplusfrontmatter convention does not make firstclass:
1. What was this created from, and how was it verified? (**provenance**)
2. How much should I trust it? (**trust**)
3. Is it still true? (**freshness**)
4. Is it the current version? (**lifecycle**)
5. Was this number produced the way we said it must be? (**attestation**)
+22
View File
@@ -0,0 +1,22 @@
---
type: Section
title: Terminology
---
# Terminology
- **Knowledge Bundle** (or **bundle**): a selfcontained, hierarchical collection of knowledge documents.
- **Concept**: a single unit of knowledge represented as one markdown document.
- **Concept ID**: the file path of the concept within the bundle, without the `.md` suffix.
- **Frontmatter**: a YAML metadata block at the top of a markdown file.
- **Body**: the markdown content following the frontmatter.
- **Link**: a standard markdown link used to express relationships between concepts.
- **Source**: a material a concept derives from, recorded in the `sources` frontmatter field.
- **Provenance**: the set of sources a concept derives from.
- **Credibility signal**: objective persource facts (author, usage_count, last_modified).
- **Actor**: identifier of who performed an action, using the convention `<producer>/<version>`, `human:<id>`, or `process:<id>`.
- **Trust tier**: level derived from the `verified` field (unverified, machineconfirmed, humanreviewed).
- **Attested Computation**: a concept (`type: Attested Computation`) that carries a sanctioned way to compute a value.
- **Executor**: runs a computation and returns a receipt.
- **Receipt**: evidence returned by an executor, inspected by an attester.
- **Attester**: deterministic code that validates a receipt.
@@ -0,0 +1,24 @@
---
type: Section
title: Bundle Structure
---
# Bundle Structure
A Knowledge Bundle is a self-contained, hierarchical collection of knowledge documents. The bundle root contains an `index.md` file that lists all concepts in the bundle. Each concept is a separate markdown file with its own frontmatter and body.
## Directory Layout
```
bundle-root/
├── index.md # Bundle-level index (conventional filename)
├── concept-a.md # Top-level concept
└── subdir/
└── concept-b.md # Nested concept; ID = "subdir/concept-b"
```
Concept IDs are the file path without `.md`. A concept at `bundle-root/subdir/concept-b.md` has ID `subdir/concept-b`.
## Index File
The `index.md` at the bundle root is a conventional entry point listing all top-level concepts. It serves as progressive disclosure for large bundles.
@@ -0,0 +1,45 @@
---
type: Section
title: Concept Documents
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Concept Documents
A knowledge concept is a document containing metadata and content. It consists of two parts: **frontmatter** and **body**. The body is the main content.
## Frontmatter
Frontmatter is YAML enclosed between `---` delimiters at the start of the document, before any other text. All frontmatter keys MUST be lowercase.
### Required Fields
| Field | Type | Description |
|-------|------|-------------|
| `type` | string | Must be one of: `Rule`, `Section`, `Example`, `Template` |
| `title` | string | Human-readable title of the concept |
### Optional Fields
#### Provenance Family (`sources`)
List of URIs or paths identifying sources used to produce this document. Values may reference files, URLs, or external resources.
#### Trust Family (`generated`, `verified`)
- `generated`: boolean — whether the document was produced by an automated system
- `verified`: boolean — whether a human has reviewed the document's correctness
#### Lifecycle Family (`status`, `stale_after`)
- `status`: string — lifecycle status: `draft`, `current`, `deprecated`
- `stale_after`: date-string — after which this document should no longer be relied upon
### Conventions
- Unknown additional frontmatter entries MAY be included
- New conventional section headings can be added to bodies
+21
View File
@@ -0,0 +1,21 @@
---
type: Section
title: Cross-linking and Paths
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Cross-linking and Paths
Concepts in a bundle can reference each other using paths relative to the bundle root. The path format is `bundle/path/to/concept` without the `.md` extension.
## Link Format
```markdown
See [concept-a](@/path/to/concept).
```
The `@/` prefix indicates a local bundle link. This allows concepts to form a graph of relationships rather than being isolated documents.
+23
View File
@@ -0,0 +1,23 @@
---
type: Section
title: Provenance (Sources)
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Provenance (Sources)
The `sources` frontmatter field records the origin of a document. It is a list of identifiers (typically file names or URLs) that point to the original material used to create the concept.
## Usage
```yaml
sources:
- SPEC.md
- https://example.com/related-spec
```
Including sources ensures traceability, enables impact analysis when source material changes, and supports proper attribution.
+18
View File
@@ -0,0 +1,18 @@
---
type: Section
title: Trust (Generated & Verified)
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Trust (Generated & Verified)
Two boolean flags express the trustworthiness of a document:
- `generated`: set to `true` when the document was created automatically (e.g., by a script or tool).
- `verified`: set to `true` only after a human reviewer has confirmed the content.
Both flags start as `true`/`false` respectively; they must be updated manually when verification occurs.
+18
View File
@@ -0,0 +1,18 @@
---
type: Section
title: Lifecycle (Status & Stale After)
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Lifecycle (Status & Stale After)
Two fields describe a document's lifecycle:
- `status`: one of `draft`, `current`, `deprecated`, or `archived`.
- `stale_after`: an ISO8601 date after which the document should be reviewed.
These fields help automated tools decide when to flag a concept for revision.
@@ -0,0 +1,21 @@
---
type: Section
title: Actor Convention
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Actor Convention
The `actor` frontmatter field records the identity that created or maintains a concept. It follows the pattern `<type>/<name>` where `<type>` is `person`, `organization`, or `automation`.
## Example
```yaml
actor: person/jdoe
```
Using a structured actor name enables automated attribution and accountability.
@@ -0,0 +1,23 @@
---
type: Section
title: Attested Computation (§10)
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Attested Computation (§10)
The `computation` field records a deterministic computation that can be rerun to verify a documents content. It typically includes a reference to a script or function and its inputs.
## Example
```yaml
computation:
script: verify_hash.sh
args: ["{{file}}", "{{expected_hash}}"]
```
When the computation succeeds, the document can be marked `verified: true`.
+24
View File
@@ -0,0 +1,24 @@
---
type: Section
title: Index Files
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Index Files
An `index.md` file at the root of a bundle lists the concepts it contains. It provides a table of contents for humans and a machinereadable list for tools.
## Example
```markdown
# Index
- [Concept A](@/concepts/a)
- [Concept B](@/concepts/b)
```
Index files should be kept in sync with the bundle's actual contents.
+21
View File
@@ -0,0 +1,21 @@
---
type: Section
title: Log Files
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Log Files
A `log.md` file records incremental changes to a concept. Each entry includes a timestamp, the actor, and a short description of the modification.
## Example Entry
```markdown
- 2026-03-15T12:34:56Z person/jdoe: Updated description of the `status` field.
```
Log files enable audit trails and support automated diff generation.
+21
View File
@@ -0,0 +1,21 @@
---
type: Section
title: Changes from v0.1
sources: [SPEC.md]
generated: true
verified: false
status: current
stale_after: 2026-12-31
---
# Changes from v0.1
This section records the major updates introduced in version0.2 of the OKF specification compared to v0.1.
- Added `stale_after` field to support automated review scheduling.
- Introduced `actor` field for attribution of changes.
- Formalised `computation` field for attested reproducibility.
- Standardised frontmatter boolean flags `generated` and `verified`.
- Expanded crosslink syntax with the `@/` prefix.
These changes improve traceability, accountability, and automation support.
+68 -18
View File
@@ -3,8 +3,12 @@ type: Architecture
title: wsg_lib Engine Architecture title: wsg_lib Engine Architecture
description: Technical architecture and design principles of the wsg_lib rendering engine description: Technical architecture and design principles of the wsg_lib rendering engine
tags: [architecture, rendering, graphics, wgpu, engine] tags: [architecture, rendering, graphics, wgpu, engine]
status: stable actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
--- ---
# Architecture du Moteur wsg_lib # Architecture du Moteur wsg_lib
@@ -14,8 +18,12 @@ wsg_lib est un moteur de rendu modulaire basé sur wgpu. Il adopte une architect
## 1. Philosophie et Principes ## 1. Philosophie et Principes
- **Abstraction vs Transparence** : Le moteur masque la complexité (wgpu, winit, gestion des Frame) via `App`, tout en exposant les briques élémentaires pour les utilisateurs avancés. - **Abstraction vs Transparence** : Le moteur masque la complexité (wgpu, winit, gestion des Frame) via `App`, tout en exposant les briques élémentaires pour les utilisateurs avancés.
- **Approche orientée Scène** : Le rendu repose sur la composition d'une `Scene` contenant les entités, matériaux et géométries. - **Architecture GPU-Driven** : Le CPU est le cerveau logique (gestion de la scène, IA, réseau), le GPU est l'exécutant visuel. Le moteur délègue au GPU le calcul des World Matrices, le Frustum Culling et la génération des listes de dessin indirectes — évitant ainsi les goulets d'étranglement PCIe.
- **Pipeline Data-Driven** : Les ressources (Shaders, Meshes, Materials) sont découplées. Le `PipelineCache` gère automatiquement la compilation et la réutilisation des pipelines GPU. - **Pipeline à deux passes** : Chaque frame suit un ordre strict : **Compute Pass** (calculs GPU) → **Render Pass** (dessin indirect). Les barrières de mémoire sont gérées automatiquement par le driver.
- **Ressources persistantes en VRAM** : Les buffers essentiels (Transform, Matrix, BoundingBox, Indirect Draw) vivent d'une frame à l'autre sans redescendre vers le CPU.
> **Note sur la synchronisation** : La première itération utilise un **single buffer** pour les buffers Transform et Matrix (voir §4B). Le double buffering n'est pas nécessaire tant que `desired_maximum_frame_latency` ≥ 3 ou que le moteur fonctionne en FIFO avec une latence de ≥ 2 frames — dans ce cas, le GPU est toujours au moins 2 frames derrière, éliminant tout risque de collision CPU/GPU. Le double buffering sera ajouté uniquement si le moteur atteint des fréquences élevées (> 90 fps) où le CPU peut écrire une frame pendant que le GPU lit encore la précédente.
- **Lecture seule pendant render()** : La Scene est immuable durant le Render. L'utilisateur ne modifie que dans `update()` ; toute tentative de mutation pendant le rendu bloque les données du GPU.
- **Pipeline Cache** : Les shaders et pipelines sont compilés une fois puis réutilisés via `Arc`. Aucun readback (`map_async`) n'est effectué sauf débug critique.
## 2. Organisation des Modules (`lib/src/`) ## 2. Organisation des Modules (`lib/src/`)
@@ -38,18 +46,23 @@ La façade `App` orchestre la boucle de jeu. Elle encapsule :
### Le trait `AppHandler` ### Le trait `AppHandler`
L'utilisateur implémente ce trait pour définir la logique métier : L'utilisateur implémente ce trait pour définir la logique métier. Les deux méthodes sont appelées **dans l'ordre strict** à chaque frame :
```rust ```rust
pub trait AppHandler { pub trait AppHandler {
// Appelé avant la préparation de la frame // Phase Update — écriture des Transform bruts (CPU → GPU via buffer mappé).
// Seules les données logiques changent ici (position, rotation, échelle).
fn update(&mut self, _app: &mut App) {} fn update(&mut self, _app: &mut App) {}
// Appelé au moment de la présentation // Phase Compute + Render — déclenche un Compute Pass puis un Render Pass.
// La Scene est en lecture seule : aucun état métier ne doit être modifié.
fn render(&mut self, app: &mut App); fn render(&mut self, app: &mut App);
} }
``` ```
- **`update()`** : appelé en premier. L'utilisateur peut modifier librement la scène (transformations, ajout/suppression d'entités). Ces modifications sont synchronisées vers le GPU via un **single buffer** Transform avant la passe de calcul.
- **`render()`** : appelé après. Il ne sert qu'à injecter du rendu personnalisé (debug, HUD, etc.). La Scene reste immuable : aucune mutation d'état métier.
## 4. Workflow et Cycle de Vie ## 4. Workflow et Cycle de Vie
### A. Initialisation (Configuration) ### A. Initialisation (Configuration)
@@ -59,21 +72,47 @@ pub trait AppHandler {
- **Matériaux** : Créés avec un shader associé. Un mesh sans matériau explicite utilise `basic_shader` par défaut. - **Matériaux** : Créés avec un shader associé. Un mesh sans matériau explicite utilise `basic_shader` par défaut.
- **Scene** : Assemblage des objets. L'utilisateur peuple la scène via `app.scene`. - **Scene** : Assemblage des objets. L'utilisateur peuple la scène via `app.scene`.
### B. Boucle de Rendu (Automatisée) ### B. Boucle de Rendu — Pipeline GPU-Driven
Le moteur gère la renderloop interne : Le moteur gère la renderloop interne via un pipeline à **deux passes séquentielles** :
1. **Update** : Appel à `AppHandler::update`. ```
2. **Acquisition** : Gestion interne de `wgpu::SurfaceTexture`. [ CPU : Envoi des Transforms bruts ]
3. **Render** : Appel à `AppHandler::render` où l'utilisateur exécute `app.render(scene)`.
4. **Présentation** : Gestion interne de `present()`. [ Pass 1 : Compute (World Matrices + Frustum Culling + Indirect Draw Buffer) ]
↓ (Barrière de mémoire automatique par le driver)
[ Pass 2 : Render (Draw Indexed Indirect basé sur les objets visibles) ]
```
Étape par étape :
1. **Update** (`AppHandler::update`) — L'utilisateur modifie la scène (transformations, entités). Ces changements sont synchronisés vers le GPU via un **single buffer** Transform avant la passe de calcul.
> La synchronisation est assurée par le pipeline wgpu : `queue.submit()` après le compute pass garantit que les données Transform sont valides avant le render pass suivant. Aucun double buffering n'est nécessaire tant que la latence maximale de la surface (via `desired_maximum_frame_latency`) est ≥ 3.
2. **Compute Pass** — Un compute shader lit les Transform bruts, calcule les World Matrices finales, effectue le Frustum Culling par AABB, et remplit l'Indirect Draw Buffer avec les identifiants des objets visibles.
3. **Render Pass** — Le CPU émet une unique commande `draw_indexed_indirect`. Le GPU pioche dans l'Indirect Draw Buffer et dessine uniquement les objets visibles, sans intervention du CPU.
4. **Présentation** — La surface est présentée à l'écran.
L'ordre d'appel des méthodes sur le `CommandEncoder` (`begin_compute_pass` puis `begin_render_pass`) garantit l'exécution séquentielle. Les barrières de mémoire entre passes sont insérées automatiquement par le pilote.
#### Ressources VRAM persistantes (d'une frame à l'autre)
| Buffer | Rôle | Type wGPU | Direction du flux |
|--------|------|-----------|-------------------|
| Transform Buffer | Positions/rotations/échelles brutes | Storage Buffer | CPU → GPU |
| Matrix Buffer | World Matrices finales calculées | Storage Buffer | GPU (Calculé) → GPU (Lu par Render) |
| Bounding Box Buffer | AABB de chaque mesh pour culling | Storage Buffer | CPU → GPU (Statique) |
| Indirect Draw Buffer | Liste dynamique des objets à dessiner | Indirect + Storage | GPU (Rempli par Compute) → GPU (Lu par Render) |
> **Synchronisation single buffer** : Les buffers Transform et Matrix utilisent un **single buffer** en phase initiale. Le CPU écrit dans le buffer pendant `update()`, puis le compute shader lit les données au frame suivant via `queue.submit()` qui garantit la séquence d'exécution. Cette approche fonctionne correctement tant que la surface a une latence maximale ≥ 2 frames (configuré via `desired_maximum_frame_latency`). Le double buffering sera ajouté uniquement si des artefacts visuels apparaissent à haute fréquence (typiquement > 90 fps sur machines rapides).
Toutes ces données vivent en VRAM — aucun readback (`map_async`) n'est effectué sauf débug critique. Le CPU fait confiance à sa propre structure de données initiale pour la logique métier.
## 5. Accès Avancé ## 5. Accès Avancé
Les utilisateurs souhaitant ignorer l'abstraction `App` peuvent accéder directement à : Les utilisateurs souhaitant ignorer l'abstraction `App` peuvent accéder directement à :
- `wsg_lib::core::Context` et `Renderer` pour gérer manuellement les RenderPass. - `wsg_lib::core::Context` et `Renderer` pour gérer manuellement les Compute Pass et RenderPass.
- `wsg_lib::pipeline::PipelineCache` pour des besoins de shaders personnalisés. - `wsg_lib::pipeline::PipelineCache` pour des besoins de shaders personnalisés (compute + render).
- `winit` pour la gestion précise des événements système. - `winit` pour la gestion précise des événements système.
## 6. Structure des données (pour LLM) ## 6. Structure des données (pour LLM)
@@ -81,11 +120,22 @@ Les utilisateurs souhaitant ignorer l'abstraction `App` peuvent accéder directe
``` ```
App (Facade) -> Scene (Conteneur) -> Entities -> Mesh + Material (Shader) App (Facade) -> Scene (Conteneur) -> Entities -> Mesh + Material (Shader)
| |
+-> Renderer (WGPU) <-> PipelineCache (Shaders) +-> Renderer (WGPU)
├── Compute Pass : World Matrices + Frustum Culling → Indirect Draw Buffer
└── Render Pass : draw_indexed_indirect (objets visibles uniquement)
VRAM persistante : Transform Buffer → Matrix Buffer → BoundingBox Buffer → Indirect Draw Buffer
Single buffer (phase initiale) : Update écrit, Compute lit au frame suivant — garanti par queue.submit()
[À venir] Double buffering : buffers Transform/Matrix dupliqués + swap entre frames
``` ```
## Notes pour l'implémentation future ## Notes pour l'implémentation future
- `app.render(scene)` : Cette méthode doit devenir l'API principale pour le rendu de la scène complète. - **`render()` ne prend pas de scène en argument** — elle déclenche automatiquement le Compute Pass puis le Render Pass sur la scène actuelle. Pour injecter du rendu personnalisé, utiliser ce point d'extension sans modifier l'état métier.
- Trait `AppHandler` : Il est recommandé de faire passer la `Scene` ou une référence à celle-ci comme argument ou de permettre à `AppHandler` d'être le lieu où la `Scene` est manipulée (ex : `MyGame { scene: Scene, ... }`). - **Trait `AppHandler`** : Le `update()` est le seul endroit où muter la scène. La `Scene` peut être stockée directement dans l'implémentation (`MyGame { scene: Scene, ... }`) ou passée via argument selon les besoins ergonomiques.
- `PipelineCache` : Son utilisation doit être invisible pour l'utilisateur standard lors de la création d'un `Material`. - **`PipelineCache`** : Invisible pour l'utilisateur standard lors de la création d'un `Material`, mais accessible publiquement pour shaders compute personnalisés et pipelines avancés.
- **Compute shader par défaut** : Un compute shader intégré gère le calcul des World Matrices et le Frustum Culling. Les utilisateurs avancés peuvent le remplacer entièrement via `PipelineCache`.
- **Synchronisation** : Toujours appeler `begin_compute_pass` avant `begin_render_pass` sur le même `CommandEncoder`. Les barrières entre passes sont automatiques — ne jamais insérer de barrière manuelle sauf besoin critique.
- **Synchronisation single buffer (phase initiale)** : La séquence `queue.submit()` après chaque compute pass garantit que les données Transform sont valides avant le render pass suivant. Aucun conflit de lecture/écriture n'est possible tant que `desired_maximum_frame_latency` ≥ 3.
- **Double Buffering (future migration)** : Sera implémenté sur les buffers Transform et Matrix seulement, pas sur BoundingBox ni Indirect Draw. Le switch se résume à : dupliquer ces deux buffers, ajouter une méthode `swap()` appelée dans `AboutToWait`, modifier les bind groups pour pointer vers l'index courant. Pas besoin de refonte architecturale.
+5 -1
View File
@@ -3,8 +3,12 @@ type: Technical Specification
title: Generational Arena Resource Management with slotmap title: Generational Arena Resource Management with slotmap
description: Technical specification for efficient and safe resource management using generational arenas implemented via the slotmap crate description: Technical specification for efficient and safe resource management using generational arenas implemented via the slotmap crate
tags: [architecture, resources, performance, safety, slotmap, arena] tags: [architecture, resources, performance, safety, slotmap, arena]
status: stable actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
--- ---
# Fiche Technique : Gestion des Ressources avec des Arènes Générationalles (`slotmap`) # Fiche Technique : Gestion des Ressources avec des Arènes Générationalles (`slotmap`)
+6 -2
View File
@@ -3,8 +3,12 @@ type: Technical Specification
title: GPU-Driven 3D Rendering Architecture with wGPU title: GPU-Driven 3D Rendering Architecture with wGPU
description: Technical specification for GPU-driven 3D rendering architecture using wgpu, focusing on CPU-GPU workload distribution and performance optimization description: Technical specification for GPU-driven 3D rendering architecture using wgpu, focusing on CPU-GPU workload distribution and performance optimization
tags: [architecture, rendering, gpu, cpu, performance, wgpu] tags: [architecture, rendering, gpu, cpu, performance, wgpu]
status: stable actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
--- ---
Architecture de Rendu 3D GPU-Driven avec wGPU : Architecture de Rendu 3D GPU-Driven avec wGPU :
@@ -38,7 +42,7 @@ L'exécution des tâches s'appuie sur une structure séquentielle stricte au sei
``` ```
Étape par étape : Étape par étape :
- Mise à jour CPU (Minimaliste) : Le CPU écrit les transformations brutes (Transform) modifiées dans un buffer GPU mappé (via un mécanisme de Double Buffering pour éviter les conflits de lecture/écriture). - Mise à jour CPU (Minimaliste) : Le CPU écrit les transformations brutes (Transform) modifiées dans un buffer GPU mappé (single buffer en phase initiale — la synchronisation est assurée par `queue.submit()` qui garantit la séquence d'exécution). Double buffering sera ajouté uniquement si des artefacts apparaissent à haute fréquence (> 90 fps).
- Pass de Calcul (Compute Pass) : - Pass de Calcul (Compute Pass) :
- Calcul des World Matrices : Un compute shader lit les transformations brutes et génère la matrice 4x4 finale pour chaque mesh. - Calcul des World Matrices : Un compute shader lit les transformations brutes et génère la matrice 4x4 finale pour chaque mesh.
- Frustum Culling GPU : Le même compute shader (ou un compute pass dédié) compare la Bounding Box (AABB) de chaque objet avec les plans de la caméra (matrice de projection/vue). - Frustum Culling GPU : Le même compute shader (ou un compute pass dédié) compare la Bounding Box (AABB) de chaque objet avec les plans de la caméra (matrice de projection/vue).
+5 -1
View File
@@ -3,8 +3,12 @@ type: Technical Specification
title: Rendering Architecture: Update/Render Cycle and Data Management title: Rendering Architecture: Update/Render Cycle and Data Management
description: Technical specification for the rendering architecture of wsg_lib, defining strategies for mutability and data management to maximize performance and memory safety in Rust description: Technical specification for the rendering architecture of wsg_lib, defining strategies for mutability and data management to maximize performance and memory safety in Rust
tags: [architecture, rendering, rust, performance, memory-safety] tags: [architecture, rendering, rust, performance, memory-safety]
status: stable actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
--- ---
# Architecture de Rendu : Cycle Update/Render et Gestion des Données # Architecture de Rendu : Cycle Update/Render et Gestion des Données
+7 -1
View File
@@ -3,8 +3,12 @@ type: Technical Specification
title: Frame Loop Architecture title: Frame Loop Architecture
description: Technical specification for the frame loop architecture in wsg_lib, detailing the immutable frame lifetime cycle and resource management description: Technical specification for the frame loop architecture in wsg_lib, detailing the immutable frame lifetime cycle and resource management
tags: [architecture, rendering, frame-loop, gpu, wgpu] tags: [architecture, rendering, frame-loop, gpu, wgpu]
status: stable actor: person/jerome
sources: []
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z } generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
verified: true
status: current
stale_after: 2027-01-31
--- ---
# La Boucle de Rendu (Frame Loop) # La Boucle de Rendu (Frame Loop)
@@ -36,4 +40,6 @@ Avec notre nouvelle architecture "Atelier", la distinction est devenue encore pl
| CommandEncoder | Par-Frame | Ton "carnet de notes" temporaire pour les ordres du GPU. | | CommandEncoder | Par-Frame | Ton "carnet de notes" temporaire pour les ordres du GPU. |
| TextureView | Par-Frame | Fenêtre temporaire sur la texture active du swapchain. | | TextureView | Par-Frame | Fenêtre temporaire sur la texture active du swapchain. |
> **Ressources GPU persistantes (single buffer)** : Les buffers Transform et Matrix sont stockés en VRAM avec un **single buffer** en phase initiale. Le CPU écrit pendant `update()`, le compute shader lit au frame suivant via la séquence garantie par `queue.submit()`. Double buffering sera ajouté uniquement si des artefacts visuels apparaissent à haute fréquence.
--- ---
+217
View File
@@ -0,0 +1,217 @@
Diagnose log at 2026-07-31T18:48:16Z
AppPath: /usr/local/bin/git-credential-manager
InstallDir: /usr/local/share/gcm-core/
Version: 2.6.1+786ab03440ddc82e807a97c0e540f5247e44cec6
------------
Diagnostic: Environment
Skipped: False
Success: True
Exception: None
Log:
OSType: Linux
OSVersion: Ubuntu 24.04.4 LTS
Reading environment variables... OK
Variables:
GSM_SKIP_SSH_AGENT_WORKAROUND=true
ZED_TERM=true
GEMINI_API_KEY=AIzaSyAcgradZn-Y0VthnobNSA4o82N7X5bL_8k
GDK_BACKEND=wayland,x11
QTWEBENGINE_DICTIONARIES_PATH=/usr/share/hunspell-bdic/
ANDROID_HOME=/home/jerome/Android/Sdk
COSMIC_PANEL_ANCHOR=Left
_=/usr/bin/git
ALACRITTY_WINDOW_ID=4294967349
XDG_SESSION_DESKTOP=cosmic
QT_ACCESSIBILITY=1
COSMIC_PANEL_SIZE=L
HOME=/home/jerome
ANDROID_NDK_HOME=/home/jerome/Android/Sdk/ndk/29.0.14206865
GTK_IM_MODULE=ibus
JAVA_HOME=/home/jerome/android-studio-panda2-linux/android-studio/jbr
PATH=/usr/lib/git-core:/home/jerome/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/jerome/android-studio-panda2-linux/android-studio/jbr/bin:/usr/local/cuda/bin:/home/jerome/.opencode/bin:/home/jerome/.bun/bin:/run/user/1000/fnm_multishells/71636_1785523522033/bin:/home/jerome/.local/share/fnm:/home/jerome/.local/bin:/home/jerome/.local/bin:/home/jerome/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/jerome/android-studio-panda2-linux/android-studio/jbr/bin:/usr/local/cuda/bin:/home/jerome/.opencode/bin:/home/jerome/.bun/bin:/run/user/1000/fnm_multishells/13158_1785514517963/bin:/home/jerome/.local/share/fnm:/home/jerome/.local/bin:/home/jerome/.local/bin:/home/jerome/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/jerome/android-studio-panda2-linux/android-studio/jbr/bin:/usr/local/cuda/bin:/home/jerome/.opencode/bin:/home/jerome/.bun/bin:/run/user/1000/fnm_multishells/12525_1785514517360/bin:/home/jerome/.local/share/fnm:/home/jerome/.nvm/versions/node/v22.20.0/bin:/home/jerome/.local/bin:/home/jerome/.cargo/bin:/home/jerome/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/jerome/.lmstudio/bin:/usr/local/go/bin:/home/jerome/Android/Sdk/emulator:/home/jerome/Android/Sdk/platform-tools:/home/jerome/Android/Sdk/cmdline-tools/latest/bin:/home/jerome/Android/Sdk/build-tools:/home/jerome/.lmstudio/bin:/home/jerome/.lmstudio/bin:/usr/local/go/bin:/home/jerome/Android/Sdk/emulator:/home/jerome/Android/Sdk/platform-tools:/home/jerome/Android/Sdk/cmdline-tools/latest/bin:/home/jerome/Android/Sdk/build-tools:/home/jerome/.lmstudio/bin:/home/jerome/.lmstudio/bin:/usr/local/go/bin:/home/jerome/Android/Sdk/emulator:/home/jerome/Android/Sdk/platform-tools:/home/jerome/Android/Sdk/cmdline-tools/latest/bin:/home/jerome/Android/Sdk/build-tools:/home/jerome/.lmstudio/bin
TERM=xterm-256color
QT_IM_MODULE=ibus
X_PRIVILEGED_WAYLAND_SOCKET=114
FNM_ARCH=x64
CLUTTER_IM_MODULE=ibus
LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/lib64:/usr/local/cuda/lib64
XDG_VTNR=2
FNM_RESOLVE_ENGINES=true
DEBUGINFOD_URLS=https://debuginfod.ubuntu.com
GIT_TRACE2_PARENT_SID=d6e89d30-0e68-496d-b026-b9696e2d470f
ALBERT_API_KEY=sk-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjozNDYsInRva2VuX2lkIjo0NDgyLCJleHBpcmVzX2F0IjoxNzkzMjI4NDAwfQ.mRlU8oR4oNHY5QgST29bM9kaJ21vM0yhwGsUW0QVwpM
COLORTERM=truecolor
GDMSESSION=cosmic
COSMIC_PANEL_PADDING_OVERLAP=0.5
INFOPATH=/home/linuxbrew/.linuxbrew/share/info:/home/linuxbrew/.linuxbrew/share/info:/home/linuxbrew/.linuxbrew/share/info:
MOZ_ENABLE_WAYLAND=1
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
LESSCLOSE=/usr/bin/lesspipe %s %s
USER=jerome
GIT_EXEC_PATH=/usr/lib/git-core
PANEL_NOTIFICATIONS_FD=21
GTK_MODULES=gail:atk-bridge
SHLVL=1
QT_ENABLE_HIGHDPI_SCALING=1
XDG_SEAT=seat0
NVM_DIR=/home/jerome/.nvm
IM_CONFIG_CHECK_ENV=1
NVM_CD_FLAGS=
WINDOWID=4294967349
XDG_CURRENT_DESKTOP=COSMIC
COSMIC_PANEL_SPACING=4
FNM_VERSION_FILE_STRATEGY=local
X_MINIMIZE_APPLET=false
XDG_SESSION_CLASS=user
FNM_LOGLEVEL=info
QT_QPA_PLATFORMTHEME=qt6ct
SHELL=/bin/bash
COSMIC_PANEL_OUTPUT=DP-1
BUN_INSTALL=/home/jerome/.bun
FNM_MULTISHELL_PATH=/run/user/1000/fnm_multishells/71636_1785523522033
IM_CONFIG_PHASE=1
QT_AUTO_SCREEN_SCALE_FACTOR=1
LIBVIRT_DEFAULT_URI=qemu:///system
LOGNAME=jerome
USERNAME=jerome
XDG_CONFIG_DIRS=/etc/xdg/xdg-cosmic:/etc/xdg
NVM_BIN=/home/jerome/.nvm/versions/node/v22.20.0/bin
DCONF_PROFILE=/usr/share/dconf/profile/cosmic
XMODIFIERS=@im=ibus
LANG=fr_FR.UTF-8
TERM_PROGRAM_VERSION=1.13.1+stable.332.00bd72e7838f4b875a913cd112b47a0ebe1ca62b
DESKTOP_SESSION=cosmic
HOMEBREW_PREFIX=/home/linuxbrew/.linuxbrew
WAYLAND_DISPLAY=wayland-1
ZED_ENVIRONMENT=worktree-shell
XDG_SESSION_ID=2
PWD=/home/jerome/scripts/rust/wsg
NVM_INC=/home/jerome/.nvm/versions/node/v22.20.0/include/node
FNM_DIR=/home/jerome/.local/share/fnm
IUT_API_KEY=eviv-78bulgroz-78
HOMEBREW_CELLAR=/home/linuxbrew/.linuxbrew/Cellar
LESSOPEN=| /usr/bin/lesspipe %s
XDG_RUNTIME_DIR=/run/user/1000
TERM_PROGRAM=zed
COSMIC_PANEL_BACKGROUND=ThemeDefault
DISPLAY=:1
FNM_COREPACK_ENABLED=false
XDG_SESSION_TYPE=wayland
OLDPWD=/home/jerome
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.crdownload=00;90:*.dpkg-dist=00;90:*.dpkg-new=00;90:*.dpkg-old=00;90:*.dpkg-tmp=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:*.swp=00;90:*.tmp=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:
_JAVA_AWT_WM_NONREPARENTING=1
FNM_NODE_DIST_MIRROR=https://nodejs.org/dist
XDG_DATA_DIRS=/usr/share/cosmic:/home/jerome/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
COSMIC_PANEL_NAME=Dock
HOMEBREW_REPOSITORY=/home/linuxbrew/.linuxbrew/Homebrew
SSH_AUTH_SOCK=/run/user/1000/gcr/ssh
QT_QPA_PLATFORM=wayland;xcb
------------
Diagnostic: File system
Skipped: False
Success: True
Exception: None
Log:
Temporary directory is '/tmp/'...
Checking basic file I/O...
Writing to temporary file '/tmp/4d2c46a5985dd9e274cc199e'... OK
Reading from temporary file '/tmp/4d2c46a5985dd9e274cc199e'... OK
Deleting temporary file '/tmp/4d2c46a5985dd9e274cc199e'... OK
Testing IFileSystem instance...
UserHomePath: /home/jerome
UserDataDirectoryPath: /home/jerome/.gcm
GetCurrentDirectory(): /home/jerome/scripts/rust/wsg
------------
Diagnostic: Networking
Skipped: False
Success: True
Exception: None
Log:
Checking networking and HTTP stack...
Creating HTTP client... OK
IsNetworkAvailable: True
Sending HEAD request to http://example.com...Sending HEAD request to https://example.com... OK
OK
Acquiring free TCP port... OK
Testing local HTTP loopback connections...
Creating new HTTP listener for http://localhost:44671/... OK
Waiting for loopback connection... OK
Writing response... OK
Waiting for response data... OK
Loopback connection data OK
------------
Diagnostic: Git
Skipped: False
Success: True
Exception: None
Log:
Getting Git version... OK
Git version is '2.43.0'
Locating current repository...Git repository at '/home/jerome/scripts/rust/wsg/.git'
OK
Listing all Git configuration... OK
Git configuration:
file:/home/jerome/.gitconfig credential.helper=
file:/home/jerome/.gitconfig credential.helper=/usr/local/bin/git-credential-manager
file:/home/jerome/.gitconfig credential.credentialstore=secretservice
file:/home/jerome/.gitconfig credential.https://dev.azure.com.usehttppath=true
file:/home/jerome/.gitconfig user.email=jerome.bousquie@ut-capitole.fr
file:/home/jerome/.gitconfig user.name=Jérôme Bousquié
file:/home/jerome/.gitconfig credential.https://codeberg.org.provider=generic
file:/home/jerome/.gitconfig credential.https://git.iut-rodez.fr.provider=generic
file:.git/config core.repositoryformatversion=0
file:.git/config core.filemode=true
file:.git/config core.bare=false
file:.git/config core.logallrefupdates=true
file:.git/config remote.origin.url=https://git.iut-rodez.fr/jerome/wsg.git
file:.git/config remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
file:.git/config branch.main.remote=origin
file:.git/config branch.main.merge=refs/heads/main
------------
Diagnostic: Credential storage
Skipped: False
Success: True
Exception: None
Log:
ICredentialStore instance is of type: CredentialStore
Writing test credential... OK
Reading test credential... OK
Deleting test credential... OK
------------
Diagnostic: Microsoft authentication (AAD/MSA)
Skipped: False
Success: True
Exception: None
Log:
Broker is not enabled.
Flow type is: Auto
Gathering MSAL token cache data... OK
CacheDirectory: /home/jerome/.local/.IdentityService
CacheFileName: msal.cache
CacheFilePath: /home/jerome/.local/.IdentityService/msal.cache
KeyringCollection:
KeyringSchemaName:
KeyringSecretLabel:
KeyringAttribute1: (,)
KeyringAttribute2: (,)
Creating cache helper... OK
Verifying MSAL token cache persistence... OK
------------
Diagnostic: GitHub API
Skipped: False
Success: True
Exception: None
Log:
Using 'https://github.com/' as API target.
Querying '/meta' endpoint... OK
+2
View File
@@ -11,6 +11,8 @@ wgpu = "30.0.0" # Vérifiez la version la plus récente
winit = "0.29" # For window management — pinned to match examples winit = "0.29" # For window management — pinned to match examples
thiserror = "2" thiserror = "2"
bytemuck = { version = "1.25.0", features = ["derive"] } bytemuck = { version = "1.25.0", features = ["derive"] }
glam = "0.33"
slotmap = "1.0"
[dev-dependencies] [dev-dependencies]
pollster = { version="0.4.0", features = ["macro"] } pollster = { version="0.4.0", features = ["macro"] }
+1
View File
@@ -32,6 +32,7 @@ pub mod pipeline;
pub mod resources; pub mod resources;
pub mod scene; pub mod scene;
pub mod utils; pub mod utils;
pub mod math;
/// Re-export of the high-level application facade for convenient top-level access. /// Re-export of the high-level application facade for convenient top-level access.
/// Users create App instances via `AppBuilder`, then call `.run(handler)` to start the application. /// Users create App instances via `AppBuilder`, then call `.run(handler)` to start the application.
+28
View File
@@ -0,0 +1,28 @@
//! # Geometry Module
//!
//! Defines the `Geometry` struct for storing vertex data of 3D meshes.
//! This module handles the core geometric representation used by meshes.
//!
//! ## Usage
//! - Stores vertex attributes (positions, normals, UVs)
//! - Used by `Mesh` to define its vertex data
//! - Passed to shaders for rendering
//!
//! ## Related Types
//! - `Geometry`: Main struct for vertex data storage
//! - Fields: positions, normals, uvs, indices
/// Represents the geometric data of a 3D mesh.
///
/// This struct stores the core vertex attributes that define a mesh's shape.
#[derive(Debug, Clone)]
pub struct Geometry {
/// Vertex positions as an array of 3D coordinates
pub positions: Vec<[f32; 3]>,
/// Optional vertex normals for lighting calculations
pub normals: Option<Vec<[f32; 3]>>,
/// Optional texture coordinates for UV mapping
pub uvs: Option<Vec<[f32; 2]>>,
/// Optional indices for indexed rendering
pub indices: Option<Vec<u16>>,
}
+23
View File
@@ -0,0 +1,23 @@
//! # Math Module — Geometric and Transformation Utilities
//!
//! Provides core mathematical types and utilities for 3D graphics operations, including:
//! - `Transform` for object positioning, rotation, and scaling
//! - `Camera` for view and projection matrix calculations
//! - `Geometry` for mesh vertex data representation
//!
//! ## Interaction with Other Modules
//! - `scene::Scene` uses `Transform` to manage entity positions
//! - `renderer::Renderer` uses `Transform` and `Camera` to compute matrices for shaders
//! - `resources::Mesh` stores vertex data in `Geometry` format
//!
//! ## Files
//! - `transform.rs`: Defines the `Transform` struct and its conversion to matrix form
//! - `geometry.rs`: Defines the `Geometry` struct for mesh data storage
//! - `camera.rs`: Defines the `Camera` struct and view/projection matrix calculations
pub mod transform;
pub mod geometry;
// Re-exports
pub use transform::Transform;
pub use geometry::Geometry;
+45
View File
@@ -0,0 +1,45 @@
//! # Transform Module
//!
//! Defines the `Transform` struct for representing object transformations in 3D space,
//! including translation, rotation, and scale. Also provides functionality to convert
//! the transform into a 4x4 matrix for use in shaders.
//!
//! ## Usage
//! - Used by `Scene` entities to define their position in the world
//! - Converted to `Mat4` for MVP matrix calculations in the renderer
//!
//! ## Related Types
//! - `Transform`: Core struct for position/rotation/scale
//! - `to_matrix()`: Converts transform to a 4x4 matrix
use glam::{Vec3, Quat, Mat4};
/// Represents a 3D transformation with translation, rotation, and scale.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Transform {
/// Translation vector in 3D space
pub translation: Vec3,
/// Rotation as a quaternion
pub rotation: Quat,
/// Scale factors along X, Y, Z axes
pub scale: Vec3,
}
impl Transform {
/// Creates a new identity transform.
pub fn identity() -> Self {
Self {
translation: Vec3::ZERO,
rotation: Quat::IDENTITY,
scale: Vec3::ONE,
}
}
/// Converts the transform into a 4x4 transformation matrix.
///
/// # Returns
/// A `Mat4` representing the transformation matrix
pub fn to_matrix(&self) -> Mat4 {
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
}
}
+58
View File
@@ -0,0 +1,58 @@
//! # Camera Module
//!
//! Defines the `Camera` struct and related functionality for 3D viewing.
//! Supports different camera types and projection configurations.
//!
//! ## Usage
//! - Used by `Renderer` to compute view and projection matrices
//! - Configurable for perspective and orthographic projections
//! - Supports FPS-style and orbital movement patterns
//!
//! ## Related Types
//! - `Camera`: Main struct for camera configuration
//! - `view_matrix()`: Computes the view matrix
//! - `projection_matrix()`: Computes the projection matrix
use glam::{Vec3, Mat4};
/// Represents a 3D camera for viewing the scene.
///
/// The camera defines the viewpoint and projection settings for rendering.
#[derive(Debug, Clone)]
pub struct Camera {
/// Position of the camera in world space
pub position: Vec3,
/// Target point the camera is looking at
pub target: Vec3,
/// Up vector defining the camera's orientation
pub up: Vec3,
}
impl Camera {
/// Creates a new camera with specified position, target, and up vector.
pub fn new(position: Vec3, target: Vec3, up: Vec3) -> Self {
Self { position, target, up }
}
/// Computes the view matrix for this camera.
///
/// # Returns
/// A `Mat4` representing the view transformation matrix
pub fn view_matrix(&self) -> Mat4 {
Mat4::look_at_rh(self.position, self.target, self.up)
}
/// Computes the projection matrix for this camera.
///
/// # Parameters
/// - `fov`: Field of view in radians
/// - `aspect`: Aspect ratio of the viewport
/// - `near`: Near clipping plane distance
/// - `far`: Far clipping plane distance
///
/// # Returns
/// A `Mat4` representing the projection transformation matrix
pub fn projection_matrix(&self, fov: f32, aspect: f32, near: f32, far: f32) -> Mat4 {
Mat4::perspective_rh_gl(fov, aspect, near, far)
}
}