Compare commits
4 Commits
8d61e4231e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e8e9124a9d | |||
| 895965750f | |||
| 37432536dc | |||
| 81b825970a |
Generated
+8
@@ -501,6 +501,12 @@ dependencies = [
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.33.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f22fb22f065b308be0d8724e3706c7fa3fc2a6c7d6899df4cad7860e7a75436"
|
||||
|
||||
[[package]]
|
||||
name = "glow"
|
||||
version = "0.17.0"
|
||||
@@ -2323,7 +2329,9 @@ name = "wsg-lib"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"glam",
|
||||
"pollster",
|
||||
"slotmap",
|
||||
"thiserror 2.0.18",
|
||||
"wgpu",
|
||||
"winit",
|
||||
|
||||
+3
-3
@@ -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.
|
||||
|
||||
### 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
|
||||
- [ ] Créer module `math/` (ou `transform.rs`) :
|
||||
- [ ] Struct `Transform { translation: Vec3, rotation: Quat, scale: Vec3 }`
|
||||
- [ ] 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)`
|
||||
|
||||
### 1.2 Geometry & Mesh
|
||||
- [ ] Créer struct `Geometry` :
|
||||
- [ ] Créer struct `Geometry` (math/geometry.rs) :
|
||||
- [ ] `positions: Vec<[f32; 3]>` (obligatoire)
|
||||
- [ ] `indices: Option<Vec<u16>>` (optionnel)
|
||||
- [ ] `normals: Option<Vec<[f32; 3]>>` (pour Phong)
|
||||
|
||||
+22
-10
@@ -1,24 +1,36 @@
|
||||
---
|
||||
type: Reference
|
||||
title: IAgent Documentation Rules
|
||||
description: Rules and guidelines for documentation in the IAgent project, following OKF v0.2 specification
|
||||
type: Rule
|
||||
title: Documentation Rules
|
||||
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]
|
||||
status: stable
|
||||
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
|
||||
sources: [{ ref: SPEC.md }]
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
## Within a File's Code
|
||||
## Internal Steps
|
||||
|
||||
### 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.
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -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. Cross‑linking and Paths (Fragment 05)
|
||||
- Local bundle links use the `@/` prefix.
|
||||
- Paths are written without the `.md` extension.
|
||||
- Enables a graph of inter‑concept relationships.
|
||||
|
||||
## 2. Provenance – `sources` (Fragment 06)
|
||||
- `sources` records origin identifiers (files, URLs).
|
||||
- Supports traceability and impact analysis.
|
||||
|
||||
## 3. Trust – `generated` / `verified` (Fragment 07)
|
||||
- `generated: true` for automatically produced docs.
|
||||
- `verified: true` only after human review.
|
||||
|
||||
## 4. Lifecycle – `status` & `stale_after` (Fragment 08)
|
||||
- `status` values: `draft`, `current`, `deprecated`, `archived`.
|
||||
- `stale_after` ISO‑8601 date triggers review.
|
||||
|
||||
## 5. Actor Convention (Fragment 09)
|
||||
- `actor` field follows `<type>/<name>` (e.g., `person/jdoe`).
|
||||
- Provides attribution and accountability.
|
||||
|
||||
## 6. Attested Computation (§10) (Fragment 10)
|
||||
- `computation` describes a deterministic script and its arguments.
|
||||
- Successful run allows promotion to `verified: true`.
|
||||
|
||||
## 7. Index Files (Fragment 11)
|
||||
- `index.md` lists bundle concepts for humans and tools.
|
||||
- Must stay synchronized with actual content.
|
||||
|
||||
## 8. Log Files (Fragment 12)
|
||||
- `log.md` records timestamped, actor‑identified changes.
|
||||
- Enables audit trails and diff generation.
|
||||
|
||||
## 9. Changes from v0.1 (Fragment 13)
|
||||
- Introduced `stale_after`, `actor`, `computation` fields.
|
||||
- Standardised boolean flags and cross‑link 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.*
|
||||
@@ -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 machine‑generated, a consumer needs answers that a plain markdown‑plus‑frontmatter convention does not make first‑class:
|
||||
|
||||
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**)
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
type: Section
|
||||
title: Terminology
|
||||
---
|
||||
|
||||
# Terminology
|
||||
|
||||
- **Knowledge Bundle** (or **bundle**): a self‑contained, 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 per‑source 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, machine‑confirmed, human‑reviewed).
|
||||
- **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
|
||||
@@ -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.
|
||||
@@ -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` front‑matter 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.
|
||||
@@ -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.
|
||||
@@ -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 ISO‑8601 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` front‑matter 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 re‑run to verify a document’s 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`.
|
||||
@@ -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 machine‑readable 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.
|
||||
@@ -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.
|
||||
@@ -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 version 0.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 front‑matter boolean flags `generated` and `verified`.
|
||||
- Expanded cross‑link syntax with the `@/` prefix.
|
||||
|
||||
These changes improve traceability, accountability, and automation support.
|
||||
+68
-18
@@ -3,8 +3,12 @@ type: Architecture
|
||||
title: wsg_lib Engine Architecture
|
||||
description: Technical architecture and design principles of the wsg_lib rendering engine
|
||||
tags: [architecture, rendering, graphics, wgpu, engine]
|
||||
status: stable
|
||||
actor: person/jerome
|
||||
sources: []
|
||||
generated: { by: human:jerome, at: 2026-07-31T00:00:00Z }
|
||||
verified: true
|
||||
status: current
|
||||
stale_after: 2027-01-31
|
||||
---
|
||||
|
||||
# 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
|
||||
|
||||
- **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.
|
||||
- **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.
|
||||
- **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 à 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/`)
|
||||
|
||||
@@ -38,18 +46,23 @@ La façade `App` orchestre la boucle de jeu. Elle encapsule :
|
||||
|
||||
### 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
|
||||
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) {}
|
||||
|
||||
// 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);
|
||||
}
|
||||
```
|
||||
|
||||
- **`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
|
||||
|
||||
### 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.
|
||||
- **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`.
|
||||
3. **Render** : Appel à `AppHandler::render` où l'utilisateur exécute `app.render(scene)`.
|
||||
4. **Présentation** : Gestion interne de `present()`.
|
||||
```
|
||||
[ CPU : Envoi des Transforms bruts ]
|
||||
↓
|
||||
[ 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é
|
||||
|
||||
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::pipeline::PipelineCache` pour des besoins de shaders personnalisés.
|
||||
- `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 (compute + render).
|
||||
- `winit` pour la gestion précise des événements système.
|
||||
|
||||
## 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)
|
||||
|
|
||||
+-> 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
|
||||
|
||||
- `app.render(scene)` : Cette méthode doit devenir l'API principale pour le rendu de la scène complète.
|
||||
- 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, ... }`).
|
||||
- `PipelineCache` : Son utilisation doit être invisible pour l'utilisateur standard lors de la création d'un `Material`.
|
||||
- **`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`** : 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`** : 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.
|
||||
|
||||
@@ -3,8 +3,12 @@ type: Technical Specification
|
||||
title: Generational Arena Resource Management with slotmap
|
||||
description: Technical specification for efficient and safe resource management using generational arenas implemented via the slotmap crate
|
||||
tags: [architecture, resources, performance, safety, slotmap, arena]
|
||||
status: stable
|
||||
actor: person/jerome
|
||||
sources: []
|
||||
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`)
|
||||
|
||||
@@ -3,8 +3,12 @@ type: Technical Specification
|
||||
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
|
||||
tags: [architecture, rendering, gpu, cpu, performance, wgpu]
|
||||
status: stable
|
||||
actor: person/jerome
|
||||
sources: []
|
||||
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 :
|
||||
@@ -38,7 +42,7 @@ L'exécution des tâches s'appuie sur une structure séquentielle stricte au sei
|
||||
```
|
||||
|
||||
É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) :
|
||||
- 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).
|
||||
|
||||
@@ -3,8 +3,12 @@ type: Technical Specification
|
||||
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
|
||||
tags: [architecture, rendering, rust, performance, memory-safety]
|
||||
status: stable
|
||||
actor: person/jerome
|
||||
sources: []
|
||||
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
|
||||
|
||||
@@ -3,8 +3,12 @@ type: Technical Specification
|
||||
title: Frame Loop Architecture
|
||||
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]
|
||||
status: stable
|
||||
actor: person/jerome
|
||||
sources: []
|
||||
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)
|
||||
@@ -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. |
|
||||
| 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.
|
||||
|
||||
---
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
thiserror = "2"
|
||||
bytemuck = { version = "1.25.0", features = ["derive"] }
|
||||
glam = "0.33"
|
||||
slotmap = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
pollster = { version="0.4.0", features = ["macro"] }
|
||||
|
||||
@@ -32,6 +32,7 @@ pub mod pipeline;
|
||||
pub mod resources;
|
||||
pub mod scene;
|
||||
pub mod utils;
|
||||
pub mod math;
|
||||
|
||||
/// 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.
|
||||
|
||||
@@ -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>>,
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user