Compare commits
124 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff1ec56729 | |||
| a30a9a2d29 | |||
| d217c3376b | |||
| 864e075b42 | |||
| 3fe5b32de2 | |||
| 72cb9f5be6 | |||
| f708c4cd2e | |||
| c61760dafd | |||
| 18dd2ae49d | |||
| def0609383 | |||
| 19a1d20a97 | |||
| 49ebacfbfb | |||
| 68253fae41 | |||
| 2dabb73d3d | |||
| 4f1b3b4ff3 | |||
| 627c8d4eb9 | |||
| 0b801888f0 | |||
| a180b89ee6 | |||
| 3e66e31117 | |||
| 2c194cdd2e | |||
| feaf502e44 | |||
| 489499f5d2 | |||
| 39b996eb31 | |||
| 134c0aecb7 | |||
| b144dc1c18 | |||
| 69c720b86b | |||
| 1b57a25e5f | |||
| f6db7d74e2 | |||
| a1798aecb3 | |||
| 3b07f40f2d | |||
| 27416143e3 | |||
| a2a491bd5c | |||
| da7d66e1fd | |||
| 5faf4b4197 | |||
| bee0c7f223 | |||
| 216d29ae59 | |||
| e13cf1e4c7 | |||
| cd0afcda8c | |||
| d20bdc4934 | |||
| 7c35090dbd | |||
| a766784ce8 | |||
| 63952912b5 | |||
| fd0b9e2749 | |||
| 777e51efeb | |||
| 1ad0c4de37 | |||
| 7a378afad3 | |||
| d52ec7e5a9 | |||
| 813c10f3f7 | |||
| 153833deec | |||
| b617885aa2 | |||
| 5d2e7e2aab | |||
| de77f76d48 | |||
| bdc704fe8e | |||
| bce7d11b66 | |||
| 8aa755da7a | |||
| 6d58b90856 | |||
| bafca5a936 | |||
| dcf3a8564c | |||
| bc862960a7 | |||
| 597ebcfbd4 | |||
| aa2d411b0c | |||
| 061e0dc677 | |||
| 9ef94af488 | |||
| 27b4a2c392 | |||
| d5feb07ff0 | |||
| 7dff4a1238 | |||
| a8cd66dcaa | |||
| 116746f838 | |||
| a388c02ab3 | |||
| 4b4162b7d2 | |||
| 4415faa1f1 | |||
| 4c5f08d772 | |||
| 51569af7b8 | |||
| d26c676edf | |||
| d3b4a55e71 | |||
| e212e4bbd5 | |||
| 39ec9feb0e | |||
| 4a43083178 | |||
| efcbf9e972 | |||
| f11ed67452 | |||
| 3e7edcb1b7 | |||
| b9c5d0c563 | |||
| ebdb72ce0d | |||
| 34c198ebfd | |||
| 564a455520 | |||
| c33d973f12 | |||
| 396e7e4ff0 | |||
| 2c2a90264d | |||
| e02d06b8a5 | |||
| 1901075e3a | |||
| e073fc375b | |||
| bff8a16290 | |||
| a3f611e227 | |||
| b578e68c2e | |||
| 7c691a8044 | |||
| f24704091a | |||
| e6bfcbe960 | |||
| 0fa7a82175 | |||
| 82dc47a296 | |||
| 970adf4853 | |||
| 07b09c22af | |||
| 0f6860f1ae | |||
| 6ae21a2427 | |||
| 29342d796c | |||
| 60e3c92511 | |||
| 02c1fb33d0 | |||
| ce5dc8ada0 | |||
| a2cff0567e | |||
| 8cfee1ac93 | |||
| 4c5e2ed945 | |||
| 345d49f485 | |||
| a6cc028848 | |||
| 52bb1b2915 | |||
| ade301389e | |||
| 47e50d9318 | |||
| c7df58099a | |||
| 054cb975da | |||
| cf71148935 | |||
| 1b2241df49 | |||
| d7351e5f37 | |||
| 6a412c7b00 | |||
| e9fb36f9dc | |||
| 36180279b2 | |||
| 626dc47bbe |
@@ -25,12 +25,13 @@ The current prototype puts the player in a repair-oriented world where they prog
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | Purpose |
|
||||
| --------- | --------------------------------------------------- |
|
||||
| `/` | Playable 3D experience |
|
||||
| `/?debug` | Playable scene with debug GUI and overlays |
|
||||
| `/editor` | Local map, dialogue, subtitle, and cinematic editor |
|
||||
| `/docs` | In-app documentation index |
|
||||
| Route | Purpose |
|
||||
| ---------- | --------------------------------------------------- |
|
||||
| `/` | Playable 3D experience |
|
||||
| `/?debug` | Playable scene with debug GUI and overlays |
|
||||
| `/editor` | Local map, dialogue, subtitle, and cinematic editor |
|
||||
| `/gallery` | 3D model gallery for browsing project assets |
|
||||
| `/docs` | In-app documentation index |
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -98,6 +99,7 @@ Useful local URLs:
|
||||
```txt
|
||||
http://localhost:5173/?debug
|
||||
http://localhost:5173/editor
|
||||
http://localhost:5173/gallery
|
||||
http://localhost:5173/docs
|
||||
```
|
||||
|
||||
@@ -110,7 +112,7 @@ npm run format:check
|
||||
npm run build
|
||||
```
|
||||
|
||||
Regenerate runtime map data after editing `public/map_raw.json`:
|
||||
Regenerate runtime map data after editing `public/map_raw.json` that came from the hierachy node of the model Blocking.gltf:
|
||||
|
||||
```bash
|
||||
npm run map:transform
|
||||
@@ -150,11 +152,13 @@ WS ws://localhost:8000/ws
|
||||
| `docs/technical/zustand.md` | Game, settings, and subtitle stores |
|
||||
| `docs/technical/three-debugging.md` | DevTools workflow for stepping into Three.js internals |
|
||||
| `docs/technical/map-performance.md` | Map draw-call bottlenecks and optimization notes |
|
||||
| `docs/technical/map-lod.md` | Runtime map LOD presets, paths, and workflow |
|
||||
| `docs/technical/editor.md` | Editor implementation details |
|
||||
| `docs/technical/animation.md` | Animated, explodable, and reusable 3D model components |
|
||||
| `docs/user/features.md` | Implemented feature inventory |
|
||||
| `docs/user/main-feature.md` | User-facing repair-game walkthrough |
|
||||
| `docs/user/editor.md` | Editor user guide |
|
||||
| `docs/user/gallery.md` | Model gallery user guide |
|
||||
| `docs/code-review-preparation.md` | French code-review preparation support |
|
||||
|
||||
## Current Caveats
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,119 @@
|
||||
# Map LOD System
|
||||
|
||||
This document describes the runtime LOD system used by the production map.
|
||||
|
||||
## Goal
|
||||
|
||||
The map now supports two visual versions for selected models:
|
||||
|
||||
- the regular model in `public/models/<name>/`
|
||||
- the lighter model in `public/models/<name>-LOD/`
|
||||
|
||||
The runtime chooses between those paths from the active graphics preset. This keeps nearby objects visually richer while reducing the cost of distant objects.
|
||||
|
||||
## Graphics Presets
|
||||
|
||||
Presets are configured in:
|
||||
|
||||
```txt
|
||||
src/data/world/graphicsConfig.ts
|
||||
```
|
||||
|
||||
Current behavior:
|
||||
|
||||
| Preset | Chunk load distance | Fog | LOD behavior |
|
||||
| -------- | ------------------: | --- | ------------------------------------- |
|
||||
| `low` | 10m | On | Always use `*-LOD` models |
|
||||
| `medium` | 20m | On | Always use `*-LOD` models |
|
||||
| `high` | 35m | Off | Regular model up to 10m, then `*-LOD` |
|
||||
| `ultra` | 50m | Off | Regular model up to 20m, then `*-LOD` |
|
||||
|
||||
The unload distance stays slightly larger than the load distance to avoid rapid mount/unmount flickering when the player stands near a boundary.
|
||||
|
||||
## Runtime Selection
|
||||
|
||||
LOD path mapping lives in:
|
||||
|
||||
```txt
|
||||
src/data/world/mapLodConfig.ts
|
||||
```
|
||||
|
||||
The main selector is `selectMapModelPathByDistance()`. It receives:
|
||||
|
||||
- the current camera distance
|
||||
- the map model name
|
||||
- the regular model path
|
||||
- the active graphics preset
|
||||
|
||||
It returns either the regular path or the `*-LOD` path.
|
||||
|
||||
## Chunked Instanced Models
|
||||
|
||||
Repeated static assets are rendered through:
|
||||
|
||||
```txt
|
||||
src/world/map-instancing/MapInstancingSystem.tsx
|
||||
```
|
||||
|
||||
For each visible chunk, the system checks the nearest instance in that chunk. If the nearest instance is inside the high-detail threshold, the whole chunk uses the regular model. Otherwise, it uses the `*-LOD` model.
|
||||
|
||||
This is intentionally chunk-level LOD instead of per-instance LOD. It matches the existing chunk streaming architecture and avoids splitting every object into many tiny batches.
|
||||
|
||||
## Single And Generated Models
|
||||
|
||||
Single map nodes use:
|
||||
|
||||
```txt
|
||||
src/hooks/world/useMapLodModelPath.ts
|
||||
src/world/GameMap.tsx
|
||||
```
|
||||
|
||||
Some named map objects are rendered through dedicated generated components instead of the generic `GameMap` path. Those components must call `useMapLodModelPath()` directly.
|
||||
|
||||
Current dedicated generated components with LOD support:
|
||||
|
||||
```txt
|
||||
src/components/three/world/EcoleModel.tsx
|
||||
src/components/three/world/LaFabrikMapModel.tsx
|
||||
```
|
||||
|
||||
This matters for `lafabrik`: adding `public/models/lafabrik-LOD/` is not enough by itself. The component must also be connected to `useMapLodModelPath()`.
|
||||
|
||||
## Adding A New LOD Model
|
||||
|
||||
To add LOD support for a model:
|
||||
|
||||
1. Add the light model in `public/models/<name>-LOD/model.gltf`.
|
||||
2. Keep the regular model in `public/models/<name>/model.glb` or `public/models/<name>/model.gltf`.
|
||||
3. Add the mapping in `src/data/world/mapLodConfig.ts`.
|
||||
4. If the model uses a dedicated component, call `useMapLodModelPath()` in that component.
|
||||
5. Preload both paths when the component is dedicated and uses `useGLTF.preload()`.
|
||||
6. Verify the GLTF/GLB references: buffers, textures, opacity maps, and relative paths.
|
||||
|
||||
## Current LOD Models
|
||||
|
||||
The current explicit LOD mappings are:
|
||||
|
||||
```txt
|
||||
ebike
|
||||
eolienne
|
||||
pylone
|
||||
boiteimmeuble
|
||||
ecole
|
||||
immeuble1
|
||||
lafabrik
|
||||
maison1
|
||||
panneauaffichage
|
||||
talkie
|
||||
```
|
||||
|
||||
## Regression Risks
|
||||
|
||||
The most common failure modes are:
|
||||
|
||||
- the `*-LOD` folder exists but is missing from `mapLodConfig.ts`
|
||||
- a dedicated generated component keeps a hardcoded model path
|
||||
- GLTF references point to textures that were renamed during export
|
||||
- a model is added to LOD config but does not spawn through `GameMap` or `MapInstancingSystem`
|
||||
|
||||
Before committing model changes, validate both the regular and LOD folders for missing GLTF refs.
|
||||
@@ -14,12 +14,12 @@ This document tracks the current map-rendering performance pass.
|
||||
|
||||
The first performance bottleneck was draw calls. Some assets were exported as many small GLTF primitives even when they used only a few materials.
|
||||
|
||||
| Model | Instances | Meshes / primitives | Notes |
|
||||
| ---------------- | --------: | ------------------: | ---------------------------------------------------------------- |
|
||||
| `generateur` | 3 | 3152 | Worst draw-call offender. Needs asset-side mesh merging. |
|
||||
| `lafabrik` | 4 | 56 | Moderate draw calls, heavy 2048 texture set. |
|
||||
| `ecole` | 1 | 107 | One material but many primitives; should be merged. |
|
||||
| `fermeverticale` | 3 | 1 | Geometry is fine; textures are large for the visible complexity. |
|
||||
| Model | Instances | Meshes / primitives | Notes |
|
||||
| ---------------- | --------: | ------------------: | ------------------------------------------------------------------------------------ |
|
||||
| `generateur` | 3 | 3152 | Worst draw-call offender. Needs asset-side mesh merging. |
|
||||
| `lafabrik` | 4 | 474 | High primitive count; current HD GLB has embedded geometry and no external textures. |
|
||||
| `ecole` | 1 | 107 | One material but many primitives; should be merged. |
|
||||
| `fermeverticale` | 3 | 1 | Geometry is fine; textures are large for the visible complexity. |
|
||||
|
||||
`generateur` was especially expensive because three visible instances could multiply thousands of primitives into thousands of draw calls. Instancing reduces repeated instance cost, but the source asset still needs a cleaner export.
|
||||
|
||||
@@ -34,7 +34,7 @@ Estimated source primitive count versus runtime merged groups:
|
||||
| `generateur` | 3152 | 8 |
|
||||
| `ecole` | 107 | 2 |
|
||||
| `eolienne` | 118 | 8 |
|
||||
| `lafabrik` | 56 | 14 |
|
||||
| `lafabrik` | 474 | ~77 |
|
||||
|
||||
This is a code-side safety net, not a replacement for clean asset exports. Clean GLB exports with merged meshes and fewer textures remain the preferred long-term path.
|
||||
|
||||
@@ -158,9 +158,11 @@ Current runtime values:
|
||||
|
||||
```txt
|
||||
chunkSize: 35
|
||||
loadRadius: 45
|
||||
unloadRadius: 45
|
||||
updateInterval: 350ms
|
||||
low load/unload radius: 10m / 18m
|
||||
medium load/unload radius: 20m / 30m
|
||||
high load/unload radius: 35m / 45m
|
||||
ultra load/unload radius: 50m / 65m
|
||||
updateInterval: 250ms
|
||||
fog near: 30
|
||||
fog far: 45
|
||||
```
|
||||
@@ -255,7 +257,7 @@ Design/export should prioritize:
|
||||
1. Produce lower-poly `buisson`, `arbre`, `sapin`, and crop assets.
|
||||
2. Add LOD or billboard variants for far vegetation.
|
||||
3. Merge `generateur` meshes from 3152 primitives to a small number of material groups.
|
||||
4. Reduce `lafabrik` texture count and downscale flat/low-detail maps.
|
||||
4. Keep `lafabrik` exports texture-light, and merge repeated material primitives where possible.
|
||||
5. Merge `ecole` primitives because it uses a single material.
|
||||
6. Prefer runtime `.glb` or compressed runtime textures when the pipeline supports it.
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ The loading progress in `HomePage` is monotonic:
|
||||
|
||||
This prevents the overlay from jumping backward when nested loaders finish in a slightly different order.
|
||||
|
||||
After the initial map boot is complete, late loading signals no longer reopen the full-screen loading overlay. Instead, `HomePage` shows the compact `AppLoadingIndicator` while the game remains visible. This is reserved for explicit runtime reload signals such as graphics preset changes, repair-state transitions, or late world loading events; chunk streaming intentionally does not drive this indicator.
|
||||
|
||||
## World Composition
|
||||
|
||||
`src/world/World.tsx` is the main scene composer.
|
||||
@@ -74,12 +76,31 @@ It tracks:
|
||||
- `showGameStage`: true when the map is ready enough to mount gameplay content
|
||||
- `gameplayReady`: true when map, stage, and octree are all ready
|
||||
|
||||
The final game-scene readiness condition is:
|
||||
The game-scene readiness condition is:
|
||||
|
||||
```ts
|
||||
showGameStage && gameStageLoaded && octree !== null;
|
||||
```
|
||||
|
||||
Shadows are configured once when `Lighting` mounts (renderer `shadowMap.enabled`, sun
|
||||
`shadow.autoUpdate = true`, bias and frustum from `SHADOW_CONFIG` in
|
||||
`src/data/world/lightingConfig.ts`). The shadow map then refreshes every frame and
|
||||
follows the player camera through the sun's `target`. The earlier `SceneShadowWarmup`
|
||||
step has been removed — the visible loading overlay no longer waits for a forced
|
||||
shadow refresh because `autoUpdate` covers steady-state rendering.
|
||||
|
||||
### Avoiding global scene remounts
|
||||
|
||||
Heavy stage components (`GameStageContent`, `Player`, dialogues) load assets via
|
||||
`useGLTF`/`useTexture` without preload (e.g. `EbikeSpeedometer` calls `useTexture`
|
||||
when the bike mounts). To prevent any late suspension from bubbling up to the
|
||||
root `<Suspense>` boundary in `src/pages/page.tsx` and unmounting the entire
|
||||
world (which would trigger a redundant octree rebuild and shadow re-config), the
|
||||
game stage block and the spawn-player block are wrapped in their own
|
||||
`<Suspense fallback={null}>` boundaries inside `src/world/World.tsx`. Any new
|
||||
sibling that suspends late should be added inside one of these boundaries or get
|
||||
its own.
|
||||
|
||||
The debug physics scene is ready when:
|
||||
|
||||
```ts
|
||||
|
||||
@@ -20,3 +20,63 @@ If DevTools still opens a bundled file, stop the dev server, clear Vite's cached
|
||||
rm -rf node_modules/.vite
|
||||
npm run dev:three-debug
|
||||
```
|
||||
|
||||
## Visual debug toggles
|
||||
|
||||
The `Debug` folder of the runtime debug GUI exposes inspection toggles backed by
|
||||
`src/managers/stores/useDebugVisualsStore.ts`:
|
||||
|
||||
- **Show Player Model** — renders the main character GLTF in front of the
|
||||
current camera (`src/components/debug/DebugPlayerModel.tsx`). The model is
|
||||
positioned in camera-local space so it stays visible regardless of pitch.
|
||||
- **Show Octree** — overlays the collision octree as colored line segments,
|
||||
one wireframe per spatial cell (`src/components/debug/DebugOctreeVisualization.tsx`).
|
||||
Cells are colored by depth. Use it to inspect collision precision around
|
||||
doorways or passages.
|
||||
- **Octree Max Depth** — caps how deep the octree visualization recurses
|
||||
(default 6). Increase to see leaf-level subdivisions; decrease to keep the
|
||||
scene readable when the tree is large.
|
||||
|
||||
The octree visualization reads the live `Octree` instance from `World`. The
|
||||
mesh uses `depthTest: false` and a high `renderOrder`, so cells stay visible
|
||||
through opaque geometry.
|
||||
|
||||
## Shadow rendering intermittence
|
||||
|
||||
Shadows occasionally failed to render on initial load and could disappear
|
||||
mid-session even though the `Lighting` configuration ran to completion. The
|
||||
fix has two layers:
|
||||
|
||||
### Per-frame refresh (steady state)
|
||||
|
||||
The sun follows the camera, so its world matrix is dirty every frame. With
|
||||
`shadow.autoUpdate` alone, three.js can skip the shadow map re-render on a
|
||||
frame where the matrix update has happened but the renderer's internal dirty
|
||||
tracking does not pick it up. To prevent that, `Lighting.useFrame` sets
|
||||
`sun.shadow.needsUpdate = true` after the per-frame matrix updates. Shadow
|
||||
config is centralized in `src/data/world/lightingConfig.ts` (`bias=0`,
|
||||
`normalBias=0`, `cameraSize=95`).
|
||||
|
||||
### Mount-time shadow map reallocation (`useShadowMapWarmup`)
|
||||
|
||||
The merged static map and other GLTFs mount imperatively after `Lighting`,
|
||||
so the shadow render target ends up linked to a renderer state that pre-dates
|
||||
the final scene. Materials compiled at that point bake a "no shadow map"
|
||||
permutation into their shader program and silently fail to render shadows
|
||||
until a WebGL context-restore cycle (the kind triggered by Chrome DevTools
|
||||
in `?debug` runs) reallocates everything.
|
||||
|
||||
`src/hooks/three/useShadowMapWarmup.ts` replays that cycle programmatically
|
||||
without the cost of a full context loss. It runs a `useFrame` watchdog that
|
||||
samples the scene mesh count every 6 frames; once the count has been stable
|
||||
for ~1 s (or after a 5 s safety cap), it:
|
||||
|
||||
1. Disposes the directional light shadow map and nulls it. three.js
|
||||
reallocates the render target on the next render at the configured
|
||||
`mapSize`.
|
||||
2. Marks every material's `needsUpdate = true`, forcing a shader recompile
|
||||
that rebinds every program to the freshly created shadow sampler.
|
||||
3. Forces a single shadow pass and invalidates the renderer.
|
||||
|
||||
The watchdog runs once per mount and adds a single traversal every 6 frames
|
||||
during the warmup window, after which it self-terminates.
|
||||
|
||||
@@ -0,0 +1,367 @@
|
||||
# WebGL Context Lost - Investigation
|
||||
|
||||
## Résumé court
|
||||
|
||||
Le projet subit des pertes de contexte WebGL pendant les phases où le jeu active
|
||||
ou prépare le hand tracking, les interactions physiques ou le repair game.
|
||||
|
||||
Le symptôme visible côté console est :
|
||||
|
||||
```txt
|
||||
THREE.WebGLRenderer: Context Lost.
|
||||
[ERROR] [WebGL] Context lost - attempting auto-restore
|
||||
THREE.WebGLRenderer: Context Restored.
|
||||
```
|
||||
|
||||
Le problème est bloquant parce que le hand tracking et le repair game sont au
|
||||
coeur de l'expérience. Quand le contexte WebGL saute, la scène Three.js peut se
|
||||
remonter, le joueur peut revenir au spawn, le pointer lock peut être perdu, et
|
||||
les tests de gameplay deviennent instables.
|
||||
|
||||
## Ce qui fonctionne aujourd'hui
|
||||
|
||||
La page principale monte un `<Canvas>` React Three Fiber dans
|
||||
`src/pages/page.tsx`.
|
||||
|
||||
`src/world/World.tsx` compose ensuite :
|
||||
|
||||
- la scène de jeu ou la scène de test physique ;
|
||||
- le player ;
|
||||
- les systèmes visuels de monde ;
|
||||
- les gants de hand tracking ;
|
||||
- les systèmes de debug.
|
||||
|
||||
Le hand tracking est centralisé dans
|
||||
`src/providers/gameplay/HandTrackingProvider.tsx`.
|
||||
|
||||
Il peut utiliser deux sources :
|
||||
|
||||
- `browser` : MediaPipe JS dans le navigateur ;
|
||||
- `backend` : backend Python local via WebSocket.
|
||||
|
||||
L'activation est déclenchée par :
|
||||
|
||||
- certaines étapes du repair game ;
|
||||
- les zones d'interaction qui demandent explicitement les mains ;
|
||||
- la scène Physique en debug, selon les objets présents.
|
||||
|
||||
## Problème observé
|
||||
|
||||
Les context lost arrivent dans plusieurs situations :
|
||||
|
||||
- entrée dans une zone d'interaction ;
|
||||
- lancement du hand tracking ;
|
||||
- lancement d'un repair game ;
|
||||
- scène Physique avec `TestMap`, `Physics`, `AnimatedModel`, waypoints GPS et
|
||||
objets interactifs ;
|
||||
- source browser JS ;
|
||||
- source backend.
|
||||
|
||||
Le fait que le crash existe avec les deux sources indique que le problème n'est
|
||||
probablement pas limité au backend Python ni à MediaPipe JS seul. Le hand
|
||||
tracking semble être un déclencheur fort, mais il arrive au moment où plusieurs
|
||||
ressources GPU et systèmes runtime se réveillent ensemble.
|
||||
|
||||
## Pourquoi c'est bloquant
|
||||
|
||||
Ce bug bloque la feature principale du projet :
|
||||
|
||||
- le repair game dépend du hand tracking pour valider certaines actions ;
|
||||
- les interactions main sont nécessaires pour tester les objets grabbables ;
|
||||
- un context lost casse la continuité du gameplay ;
|
||||
- le joueur peut être replacé au spawn après reconstruction ;
|
||||
- le pointer lock peut être perdu ;
|
||||
- les logs deviennent difficiles à lire parce que le jeu tente de restaurer la
|
||||
scène en boucle ;
|
||||
- le comportement n'est pas fiable pour une démo ou un déploiement.
|
||||
|
||||
Tant que ce problème n'est pas stable, on ne peut pas valider correctement :
|
||||
|
||||
- la mission e-bike ;
|
||||
- la mission pylône ;
|
||||
- la mission ferme ;
|
||||
- les interactions main ;
|
||||
- le switch browser/backend ;
|
||||
- le comportement en build de production.
|
||||
|
||||
## Hypothèses principales
|
||||
|
||||
### 1. Pression GPU au lancement du hand tracking
|
||||
|
||||
MediaPipe browser peut créer ses propres ressources GPU. Si Three.js charge
|
||||
déjà beaucoup de géométries, textures, ombres et modèles, l'ajout du hand
|
||||
tracking peut faire passer le navigateur au-dessus d'une limite GPU.
|
||||
|
||||
Le stash contient une tentative de mitigation en forçant MediaPipe browser et le
|
||||
backend à utiliser le CPU.
|
||||
|
||||
### 2. Activation trop brusque du runtime mains
|
||||
|
||||
Les logs montrent des transitions rapides :
|
||||
|
||||
```txt
|
||||
Browser JS runtime starting
|
||||
Runtime source selected
|
||||
Runtime snapshot changed
|
||||
Browser JS runtime stopped
|
||||
Browser JS runtime starting
|
||||
```
|
||||
|
||||
Ce type de start/stop rapide peut provoquer :
|
||||
|
||||
- création webcam ;
|
||||
- création MediaPipe ;
|
||||
- montage des gants ;
|
||||
- update du state React ;
|
||||
- re-render du monde ;
|
||||
- stress GPU au même moment.
|
||||
|
||||
### 3. Les gants 3D sont montés trop tôt
|
||||
|
||||
Si les gants de hand tracking sont montés avant d'avoir de vraies mains
|
||||
détectées, le jeu charge et prépare des modèles GPU sans utilité immédiate.
|
||||
|
||||
Le stash contient une tentative pour ne rendre les gants que lorsqu'une main
|
||||
existe réellement dans le snapshot.
|
||||
|
||||
### 4. Re-upload textures / GLTF trop agressif
|
||||
|
||||
`src/utils/three/optimizeGLTFScene.ts` modifie des textures GLTF. Si cette
|
||||
optimisation force trop souvent `needsUpdate`, mipmaps ou anisotropy, le
|
||||
navigateur peut recharger beaucoup de textures vers le GPU.
|
||||
|
||||
Le stash limite cette pression en évitant de forcer les mipmaps et en abaissant
|
||||
l'anisotropy.
|
||||
|
||||
### 5. Permission caméra au mauvais moment
|
||||
|
||||
Demander la caméra au moment exact où le joueur entre dans une interaction ou
|
||||
lance le repair game ajoute un gros événement runtime au pire moment.
|
||||
|
||||
Le stash contient une tentative de warmup caméra pour obtenir la permission plus
|
||||
tôt et réutiliser le stream au moment où le hand tracking devient nécessaire.
|
||||
|
||||
### 6. La scène Physique ajoute du bruit
|
||||
|
||||
La scène Physique est une scène de test volontairement riche :
|
||||
|
||||
- `Physics` Rapier ;
|
||||
- `GrabbableObject` ;
|
||||
- `TriggerObject` ;
|
||||
- `RepairGame` ;
|
||||
- `AnimatedModel` ;
|
||||
- GPS preview ;
|
||||
- waypoints verts ;
|
||||
- player ;
|
||||
- debug overlay.
|
||||
|
||||
Cette richesse est normale pour une scène de test, mais elle complique
|
||||
l'investigation parce qu'elle active beaucoup de systèmes à la fois.
|
||||
|
||||
## Fichiers modifiés dans le stash
|
||||
|
||||
Le stash `stash@{0}` contient 28 fichiers modifiés, environ `+530 / -152`.
|
||||
Il ne contient pas de fichiers untracked.
|
||||
|
||||
| Fichier | Rôle dans l'investigation |
|
||||
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| `README.md` | Note sur les commandes backend depuis la racine du repo. |
|
||||
| `backend/README.md` | Documentation plus claire pour lancer le backend et réparer un `.venv` cassé. |
|
||||
| `backend/hand_tracker.py` | Force le backend MediaPipe en CPU. |
|
||||
| `docs/user/main-feature.md` | Ajustements de documentation utilisateur. |
|
||||
| `public/sounds/dialogue/subtitles/fr/electricienne.srt` | Ajustements de sous-titres, pas central pour le context lost. |
|
||||
| `public/sounds/dialogue/subtitles/fr/narrateur.srt` | Ajustements de sous-titres, pas central pour le context lost. |
|
||||
| `src/components/debug/DebugPlayerModel.tsx` | Ajustements de modèle debug player. |
|
||||
| `src/components/three/handTracking/HandTrackingGlove.tsx` | Retire le preload automatique des gants pour réduire la pression GPU. |
|
||||
| `src/components/three/interaction/GrabbableObject.tsx` | Marque les grabbables qui nécessitent vraiment le hand tracking. |
|
||||
| `src/components/three/interaction/InteractableObject.tsx` | Ajoute le flag `handTracking` aux interactables. |
|
||||
| `src/data/debug/testSceneConfig.ts` | Stabilise la scène Physique : sol, GPS, hauteur des waypoints. |
|
||||
| `src/data/handTrackingConfig.ts` | Ajoute délai d'activation, TTL warmup caméra, delegate CPU browser. |
|
||||
| `src/data/player/playerConfig.ts` | Corrige le spawn Physique avec `PLAYER_EYE_HEIGHT`. |
|
||||
| `src/hooks/debug/useSceneMode.ts` | Force `game` hors debug actif pour éviter des scènes debug en prod. |
|
||||
| `src/hooks/handTracking/useBothFistsHold.ts` | Sort le hold des deux poings de `useFrame` R3F vers `requestAnimationFrame`. |
|
||||
| `src/hooks/handTracking/useBrowserHandTracking.ts` | Encadre `detectForVideo`, release MediaPipe en cleanup, gère les erreurs. |
|
||||
| `src/hooks/three/useTerrainHeight.ts` | Ajustements terrain, liés au snap/player. |
|
||||
| `src/lib/handTracking/browserHandTracking.ts` | Force delegate CPU, garde une instance MediaPipe, ajoute `releaseBrowserHandLandmarker`. |
|
||||
| `src/lib/handTracking/handTrackingSession.ts` | Ajoute warmup caméra, cache stream, timeout et consommation du stream préparé. |
|
||||
| `src/managers/InteractionManager.ts` | Ajoute `handTrackingNearby` pour ne pas activer les mains sur toute interaction. |
|
||||
| `src/pages/page.tsx` | Gestion WebGL context lost/restored, DPR fixe, antialias off, release MediaPipe au crash. |
|
||||
| `src/providers/gameplay/HandTrackingProvider.tsx` | Ajoute activation différée, snapshot queued, warmup runtime. |
|
||||
| `src/types/interaction/interaction.ts` | Ajoute `handTracking` et `handTrackingNearby` aux types interaction. |
|
||||
| `src/utils/debug/Debug.ts` | Synchronise l'affichage du controller hand tracking source. |
|
||||
| `src/utils/three/optimizeGLTFScene.ts` | Réduit la pression GPU des textures GLTF. |
|
||||
| `src/world/World.tsx` | Ne rend les gants que si une main correspondante est détectée. |
|
||||
| `src/world/debug/TestMap.tsx` | Nettoie les logs, stabilise waypoints/GPS/scène Physique. |
|
||||
| `src/world/player/PlayerCamera.tsx` | Ajustements pointer lock/canvas ciblé. |
|
||||
|
||||
## Fichiers actuellement modifiés dans le worktree
|
||||
|
||||
Etat observé au moment de cette note :
|
||||
|
||||
| Fichier | Statut |
|
||||
| --------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| `public/models/talkie/*` | Beaucoup d'anciennes textures/fichiers `.gltf` supprimés. |
|
||||
| `public/models/talkie/model.glb` | Nouveau fichier non suivi. |
|
||||
| `src/components/three/handTracking/HandTrackingGlove.tsx` | Modifié. |
|
||||
| `src/data/debug/testSceneConfig.ts` | Modifié. |
|
||||
| `src/data/gameplay/repairMissions.ts` | Modifié. |
|
||||
| `src/data/handTrackingConfig.ts` | Modifié. |
|
||||
| `src/data/player/playerConfig.ts` | Modifié. |
|
||||
| `src/data/world/mapLodConfig.ts` | Modifié. |
|
||||
| `src/hooks/handTracking/useBrowserHandTracking.ts` | Modifié. |
|
||||
| `src/hooks/handTracking/useRemoteHandTracking.ts` | Modifié. |
|
||||
| `src/lib/handTracking/browserHandTracking.ts` | Modifié. |
|
||||
| `src/lib/handTracking/handTrackingSession.ts` | Modifié. |
|
||||
| `src/pages/page.tsx` | Modifié. |
|
||||
| `src/providers/gameplay/HandTrackingProvider.tsx` | Modifié. |
|
||||
| `src/utils/debug/Debug.ts` | Modifié. |
|
||||
| `src/utils/three/optimizeGLTFScene.ts` | Modifié. |
|
||||
| `src/world/World.tsx` | Modifié. |
|
||||
| `src/world/debug/TestMap.tsx` | Modifié. |
|
||||
| `src/world/player/Player.tsx` | Modifié. |
|
||||
| `src/world/player/PlayerCamera.tsx` | Modifié. |
|
||||
| `src/world/player/PlayerController.tsx` | Modifié. |
|
||||
| `src/components/ui/RuntimeLoadingIndicator.tsx` | Nouveau fichier non suivi. |
|
||||
| `src/hooks/handTracking/useHandTrackingRuntimeWarmup.ts` | Nouveau fichier non suivi. |
|
||||
| `src/world/player/playerRuntimeSnapshot.ts` | Nouveau fichier non suivi. |
|
||||
|
||||
Attention : les fichiers supprimés/nouveaux du talkie semblent être un sujet
|
||||
séparé du context lost. Il faut les garder séparés dans les commits.
|
||||
|
||||
## Fichiers directement impactés par le bug
|
||||
|
||||
### Canvas et WebGL
|
||||
|
||||
- `src/pages/page.tsx`
|
||||
- `src/world/World.tsx`
|
||||
- `src/utils/three/optimizeGLTFScene.ts`
|
||||
|
||||
Ces fichiers influencent directement la charge GPU, la configuration du canvas,
|
||||
les ressources GLTF et le comportement au context lost/restored.
|
||||
|
||||
### Hand tracking
|
||||
|
||||
- `src/providers/gameplay/HandTrackingProvider.tsx`
|
||||
- `src/hooks/handTracking/useBrowserHandTracking.ts`
|
||||
- `src/hooks/handTracking/useRemoteHandTracking.ts`
|
||||
- `src/hooks/handTracking/useBothFistsHold.ts`
|
||||
- `src/hooks/handTracking/useHandTrackingRuntimeWarmup.ts`
|
||||
- `src/lib/handTracking/browserHandTracking.ts`
|
||||
- `src/lib/handTracking/handTrackingSession.ts`
|
||||
- `src/data/handTrackingConfig.ts`
|
||||
- `src/components/three/handTracking/HandTrackingGlove.tsx`
|
||||
- `backend/hand_tracker.py`
|
||||
|
||||
Ces fichiers contrôlent le déclenchement, la source, la caméra, MediaPipe, le
|
||||
backend et le rendu visuel des mains.
|
||||
|
||||
### Interactions et repair game
|
||||
|
||||
- `src/components/three/interaction/GrabbableObject.tsx`
|
||||
- `src/components/three/interaction/InteractableObject.tsx`
|
||||
- `src/managers/InteractionManager.ts`
|
||||
- `src/types/interaction/interaction.ts`
|
||||
- `src/components/three/gameplay/RepairGame.tsx`
|
||||
- `src/hooks/gameplay/useRepairMissionStep.ts`
|
||||
- `src/hooks/gameplay/useRepairMovementLocked.ts`
|
||||
|
||||
Ces fichiers sont impactés parce que l'entrée dans une zone ou une étape repair
|
||||
peut déclencher le hand tracking.
|
||||
|
||||
### Player et restauration après crash
|
||||
|
||||
- `src/world/player/Player.tsx`
|
||||
- `src/world/player/PlayerCamera.tsx`
|
||||
- `src/world/player/PlayerController.tsx`
|
||||
- `src/world/player/playerRuntimeSnapshot.ts`
|
||||
- `src/data/player/playerConfig.ts`
|
||||
|
||||
Ces fichiers influencent le spawn, la caméra, le pointer lock, et la possibilité
|
||||
de récupérer la dernière position après un context lost.
|
||||
|
||||
### Scène Physique / debug
|
||||
|
||||
- `src/world/debug/TestMap.tsx`
|
||||
- `src/data/debug/testSceneConfig.ts`
|
||||
- `src/components/debug/DebugPlayerModel.tsx`
|
||||
- `src/hooks/debug/useSceneMode.ts`
|
||||
- `src/utils/debug/Debug.ts`
|
||||
|
||||
Ces fichiers ne sont pas forcément la cause racine, mais ils créent une scène de
|
||||
stress utile pour reproduire le bug.
|
||||
|
||||
## Ce que le stash essayait de corriger
|
||||
|
||||
Le stash essaye de réduire le risque de context lost avec plusieurs leviers :
|
||||
|
||||
1. passer MediaPipe browser/backend en CPU ;
|
||||
2. libérer MediaPipe quand le runtime s'arrête ou quand WebGL saute ;
|
||||
3. éviter de monter les gants sans mains détectées ;
|
||||
4. retarder l'activation du hand tracking pour éviter les start/stop violents ;
|
||||
5. demander la caméra plus tôt et réutiliser le stream ;
|
||||
6. réduire la charge GPU du canvas avec DPR fixe et antialias off ;
|
||||
7. limiter les re-uploads de textures GLTF ;
|
||||
8. distinguer les interactions qui demandent vraiment le hand tracking ;
|
||||
9. restaurer WebGL avec une limite pour éviter les boucles infinies ;
|
||||
10. conserver la position du joueur après restauration.
|
||||
|
||||
## Ce qui reste à prouver
|
||||
|
||||
Il faut encore isoler le déclencheur exact :
|
||||
|
||||
- crash avec hand tracking désactivé complètement ;
|
||||
- crash avec source browser JS seulement ;
|
||||
- crash avec source backend seulement ;
|
||||
- crash avec gants 3D désactivés ;
|
||||
- crash avec MediaPipe CPU ;
|
||||
- crash avec `AnimatedModel` de TestMap désactivé ;
|
||||
- crash avec GPS preview/waypoints désactivés ;
|
||||
- crash avec shadows/antialias/DPR réduits ;
|
||||
- crash en scène game réelle, pas seulement scène Physique.
|
||||
|
||||
## Plan d'investigation recommandé
|
||||
|
||||
1. Stabiliser le worktree et ne pas mélanger assets talkie, LOD, docs backend et
|
||||
context lost dans le même commit.
|
||||
2. Garder le stash tant que le fix final n'est pas validé.
|
||||
3. Créer un commit ou patch isolé pour les logs context lost seulement.
|
||||
4. Ajouter un switch debug qui permet de couper séparément :
|
||||
- hand tracking runtime ;
|
||||
- gants 3D ;
|
||||
- MediaPipe browser ;
|
||||
- backend ;
|
||||
- GPS preview ;
|
||||
- AnimatedModel de TestMap.
|
||||
5. Reproduire le bug avec une matrice claire.
|
||||
6. Garder les changements qui diminuent réellement les context lost.
|
||||
7. Supprimer les logs temporaires une fois le diagnostic terminé.
|
||||
|
||||
## Recommandation Git
|
||||
|
||||
Ne pas supprimer le stash maintenant.
|
||||
|
||||
Il contient du travail réel sur le context lost. Même s'il n'est pas parfait, il
|
||||
sert de trace d'investigation et contient des morceaux utiles.
|
||||
|
||||
Avant de le supprimer, sauvegarder le patch :
|
||||
|
||||
```bash
|
||||
git stash show -p stash@{0} > context-lost-stash.patch
|
||||
```
|
||||
|
||||
Ensuite seulement, si tout a été repris dans des commits propres :
|
||||
|
||||
```bash
|
||||
git stash drop stash@{0}
|
||||
```
|
||||
|
||||
## Commits logiques proposés
|
||||
|
||||
Séparer en plusieurs commits pour éviter un gros commit illisible :
|
||||
|
||||
1. `docs: document webgl context lost investigation`
|
||||
2. `fix: reduce handtracking gpu pressure`
|
||||
3. `fix: delay handtracking activation`
|
||||
4. `fix: preserve player state after webgl restore`
|
||||
5. `fix: stabilize physics debug scene`
|
||||
6. `docs: clarify backend handtracking setup`
|
||||
@@ -0,0 +1,46 @@
|
||||
# Galerie des modèles
|
||||
|
||||
La galerie est disponible sur `/gallery`. Elle permet de parcourir les modèles 3D présents dans `public/models/` sans lancer la boucle de gameplay principale.
|
||||
|
||||
## Objectif
|
||||
|
||||
Cette page sert à remercier et valoriser le travail des designers du projet La Fabrik. Chaque modèle est affiché dans un canvas dédié, avec la même skybox et le même lighting que l'expérience principale.
|
||||
|
||||
## Utilisation
|
||||
|
||||
1. Ouvrir `/gallery`.
|
||||
2. Utiliser les flèches en bas de l'écran pour passer au modèle précédent ou suivant.
|
||||
3. Tourner autour du modèle avec la souris ou le doigt.
|
||||
4. Utiliser le bouton de réglages à droite pour ouvrir ou fermer le panneau lumière.
|
||||
5. Lire le diagnostic texture discret pour savoir si le modèle chargé semble correct côté textures.
|
||||
|
||||
## Fonctionnement
|
||||
|
||||
- La liste des modèles est déclarée dans `src/data/galleryModels.ts`.
|
||||
- Le viewer utilise `@react-three/fiber` et `@react-three/drei`.
|
||||
- `OrbitControls` permet de manipuler la caméra autour du modèle.
|
||||
- `Bounds` et `Center` recadrent automatiquement le modèle actif.
|
||||
- `SkyModel` réutilise la skybox du jeu, avec un matériau non éclairé uniquement dans la galerie pour éviter que certaines faces deviennent noires avec une caméra orbitale libre.
|
||||
- Les lumières reprennent les valeurs par défaut du jeu, puis peuvent être ajustées dans le panneau latéral.
|
||||
- `OrbitControls` autorise une orbite verticale complète pour inspecter le dessous des modèles.
|
||||
- Le viewer désactive les normal maps dans la preview pour limiter les coutures visibles sur certains exports découpés en plusieurs meshes.
|
||||
- Les animations GLTF présentes dans un modèle sont lancées automatiquement.
|
||||
- Un diagnostic simple inspecte les matériaux chargés pour signaler les textures absentes ou non exploitables.
|
||||
|
||||
## Ajouter un modèle
|
||||
|
||||
1. Ajouter le dossier du modèle dans `public/models/{nom}`.
|
||||
2. Vérifier que le modèle possède un fichier chargeable, par exemple `model.gltf`, `model.glb` ou un nom explicite comme `potager.gltf`.
|
||||
3. Ajouter une entrée dans `src/data/galleryModels.ts` avec un `id`, un `name` et un `path`.
|
||||
|
||||
Exemple :
|
||||
|
||||
```ts
|
||||
{ id: "nouveau-modele", name: "Nouveau modèle", path: "/models/nouveau-modele/model.gltf" }
|
||||
```
|
||||
|
||||
## Limites connues
|
||||
|
||||
- Le navigateur ne liste pas automatiquement les dossiers de `public/models/`, donc la liste reste déclarative.
|
||||
- Les modèles très lourds peuvent prendre du temps à charger.
|
||||
- La galerie est un viewer simple : elle ne remplace pas les outils d'inspection avancée comme Blender ou le viewer d'upload.
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Binary file not shown.
+2
-227
@@ -584,22 +584,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
"position": [50.072, 2.2583, 78.7082],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Mesh",
|
||||
"position": [50.072, 2.2583, 78.7082],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
@@ -888,22 +872,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
"position": [59.1794, 2.2557, 73.349],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Mesh",
|
||||
"position": [59.1794, 2.2557, 73.349],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
@@ -1112,22 +1080,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
"position": [74.0452, 2.309, 59.2374],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Mesh",
|
||||
"position": [74.0452, 2.309, 59.2374],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arbre",
|
||||
"type": "Object3D",
|
||||
@@ -2754,22 +2706,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [73.7334, 1.1132, 54.1382],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [73.7334, 1.1132, 54.1382],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -3330,22 +3266,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [67.9046, 0.5562, 74.8395],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [67.9046, 0.5562, 74.8395],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -3714,22 +3634,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [73.5205, 0.3748, 75.9136],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [73.5205, 0.3748, 75.9136],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -3858,22 +3762,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [66.999, 1.7223, 48.3983],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [66.999, 1.7223, 48.3983],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -4914,22 +4802,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [61.3924, 0.4621, 82.2195],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [61.3924, 0.4621, 82.2195],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -5122,22 +4994,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [61.1082, 0.6236, 77.7642],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [61.1082, 0.6236, 77.7642],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -5170,22 +5026,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [53.1033, 1.6054, 63.3842],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [53.1033, 1.6054, 63.3842],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -5266,22 +5106,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [59.647, 1.5484, 59.429],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [59.647, 1.5484, 59.429],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -5410,22 +5234,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [69.2496, 0.6286, 71.5478],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [69.2496, 0.6286, 71.5478],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -6226,22 +6034,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
"position": [58.3126, 0.686, 77.9828],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Mesh",
|
||||
"position": [58.3126, 0.686, 77.9828],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "buisson",
|
||||
"type": "Object3D",
|
||||
@@ -37602,23 +37394,6 @@
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "ebike",
|
||||
"type": "Object3D",
|
||||
"role": "group",
|
||||
"position": [0, 0, 0],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "ebike",
|
||||
"type": "Object3D",
|
||||
"position": [42.2399, 4.5484, 34.6468],
|
||||
"rotation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zone1_residence",
|
||||
"type": "Object3D",
|
||||
@@ -40477,14 +40252,14 @@
|
||||
"name": "lafabrik",
|
||||
"type": "Object3D",
|
||||
"position": [59.4973, 6.2746, 64.6354],
|
||||
"rotation": [-3.1416, -0.7309, -3.1416],
|
||||
"rotation": [-3.1416, 2.4107, -3.1416],
|
||||
"scale": [1, 2, 1],
|
||||
"children": [
|
||||
{
|
||||
"name": "lafabrik",
|
||||
"type": "Mesh",
|
||||
"position": [59.4973, 6.2746, 64.6354],
|
||||
"rotation": [-3.1416, -0.7309, -3.1416],
|
||||
"rotation": [-3.1416, 2.4107, -3.1416],
|
||||
"scale": [1, 2, 1]
|
||||
}
|
||||
]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user