Les deux plans se renvoyaient la balle exactement sur la zone a construire : studio-plan mettait la 3D en lot 11 en disant "depend du chantier VR", et vr-quest-unity-plan decrivait les POI sur GLB en supposant un GLB qui arrive de quelque part. Nouveau document de frontiere, plus les corrections qu'il impose au plan Studio. v2/immersif-frontiere-plan.md (neuf) - Trois couches separees : ressources immersives (360/GLB, se vendent sans casque), consommation (SectionModel3D, ImmersiveBackground, app Quest), et le Studio comme *source d'approvisionnement* de la couche 1 et non module parallele. - Pas d'add-on casque : un seul add-on "Contenu immersif" a 70 EUR, plus le hardware et l'onboarding one-shot. Reconfirme l'arbitrage du 31/08. - Generation de scene : position revisee. Marble (World Labs) a une API depuis janvier 2026, ~0,12 $ le monde draft, export GLB. Cadre retenu = roomscale stationnaire ~3 m, pas d'environnement navigable : ~500k splats de plafond sur Quest 3 standalone, et un cas mesure a 12 fps sous Unity la ou une borne doit tenir 72. - 11 decisions de retro-compat ordonnees par cout de retrofit. Les cinq premieres touchent des lots ANTERIEURS a la 3D : pipeline d'ingestion unique (l'upload est fait par le navigateur, donc un GLB uploade ne traverse aucun traitement alors qu'un GLB genere si), normalisation canonique des GLB, invalidation des POI, lignage en colonnes typees, renommage des credits. - Mecaniques de jeu immersives notees, rien de planifie : repondre (SectionQuiz existe deja), trouver (marche aussi en web sur pano pivotant, donc se vend sans casque), ordonner (OrderedTranslationAndResource existe deja), avant/apres. v2/studio-plan.md - ImageCredits* -> StudioCredits* : une 3D coute 10 a 50 fois une image, le nom aurait menti des le lot 11. - Credits rechargeables a expiration 12 mois au lieu d'un quota mensuel. Un musee genere 200 images en trois semaines pour une expo puis rien pendant cinq mois ; un forfait mensuel se gaspille dix mois sur douze. Le CreditLedger encaisse sans changement de structure. - Le critere qui separe les deux monnaies, verifie dans le code : consomme en temps reel par le visiteur (chat, vocal) contre produit une fois par le client (images, 3D, video, TTS pre-genere). Le TTS passe donc cote Studio. Au passage : reindex et insights ne debitent rien alors qu'ils coutent. - Lot 11 ne renvoie plus en boucle au plan VR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
468 lines
26 KiB
Markdown
468 lines
26 KiB
Markdown
# Contenu immersif — frontière entre le Studio IA et le canal XR — 📦 V2
|
||
|
||
> **Statut** : document de frontière, écrit le 2026-09-11. Rien de codé.
|
||
>
|
||
> **Ce document ne remplace ni [studio-plan.md](studio-plan.md) ni [vr-quest-unity-plan.md](vr-quest-unity-plan.md).**
|
||
> Il tranche ce que ces deux plans se renvoient mutuellement en dépendance : le Studio met la 3D en
|
||
> lot 11 en disant « dépend du chantier VR », et le plan VR décrit les POI sur GLB (§9) en supposant
|
||
> un GLB qui arrive de quelque part, sans jamais dire d'où. Ce n'est pas un trou de conception, c'est
|
||
> une frontière que personne ne tient.
|
||
>
|
||
> ⚠️ **Rien ici n'est V1.** La bascule Postgres et le backlog V1 passent avant. Et le gate du Studio
|
||
> reste celui du lot 4 : si un conservateur ne produit pas 10 images cohérentes seul, aucune ligne de
|
||
> 3D ne s'écrit.
|
||
|
||
---
|
||
|
||
## 1. Les trois couches
|
||
|
||
La confusion vient de ce que « module 3D » désigne trois choses distinctes, décrites dans deux
|
||
documents différents. Les voici séparées.
|
||
|
||
### Couche 1 — Ressources immersives
|
||
|
||
Trois nouveaux types de ressource, qui s'affichent **partout où une ressource s'affiche** :
|
||
|
||
```
|
||
ResourceType += Panorama360 -- image équirectangulaire
|
||
Video360 -- vidéo équirectangulaire
|
||
Model3D -- GLB
|
||
```
|
||
|
||
Indépendant de la VR. Indépendant de l'IA. Un client web sans casque et sans Studio en profite.
|
||
|
||
⚠️ **Les trois valeurs se décident d'un coup, en une migration, en fin d'enum.** Aujourd'hui
|
||
`ResourceType` s'arrête à `Text = 10` (`Data/Resource.cs:94-110`, avec le commentaire qui interdit
|
||
d'insérer au milieu). `studio-plan.md` §5 réserve déjà `Model3D = 11`.
|
||
|
||
**Décision — `Video360` est un type distinct, pas un flag `IsEquirectangular` sur `Video`.** L'enum
|
||
distingue déjà `Image` / `ImageUrl` : un type séparé est cohérent avec l'existant et rend le filtrage
|
||
trivial dans le sélecteur de ressource, qui est le point de passage unique de toute l'app
|
||
(`select_resource_modal.dart:24` embarque `ResourcesScreen`).
|
||
|
||
### Couche 2 — Consommation
|
||
|
||
Trois usages de ces ressources :
|
||
|
||
| Usage | Porté par | Canaux |
|
||
|---|---|---|
|
||
| `SectionModel3D` + POI (titre, description, audio, multilingue) | une section | web, mobile, VR |
|
||
| `ImmersiveBackground` — fond d'une visite | `Configuration` | VR, dégradé ailleurs (§4) |
|
||
| `ImmersiveBackground` — fond du menu général | `ApplicationInstance` VR | VR |
|
||
| Rendu immersif complet | app Quest (Unity) | VR |
|
||
|
||
Le back-office XR (`Device.AppType` + onglet flotte, 8-12 j) se tient debout tout seul dans cette
|
||
couche : il rend le canal administrable et démontrable avant tout engagement sur Unity.
|
||
|
||
### Couche 3 — Studio IA
|
||
|
||
**Une source d'approvisionnement pour la couche 1, pas un module parallèle.** C'est la reformulation
|
||
qui règle la frontière : le Studio ne possède pas ses assets, il **alimente la médiathèque**, qui
|
||
reste la bibliothèque unique (`studio-plan.md` §3.0).
|
||
|
||
Ce que le Studio apporte que le client ne peut pas obtenir ailleurs, dans l'ordre de valeur :
|
||
|
||
1. **L'asset atterrit dans la médiathèque, référencé par une section, donc il part offline.**
|
||
C'est le point non réplicable. Un asset généré ailleurs est un fichier à re-uploader à la main,
|
||
et il ne part offline que s'il finit référencé par un champ de section
|
||
(`GetReferencedResourceIds`).
|
||
2. **L'identité visuelle est injectée côté serveur, jamais retapée.** La cohérence des quarante
|
||
images d'un parcours, pas l'accès au modèle.
|
||
3. **Le bon format, la bonne dimension, le bon prompt contextuel** — le titre et la description de
|
||
la fiche alimentent le prompt, la validation affecte directement au champ cible.
|
||
|
||
---
|
||
|
||
## 2. Ce que chaque couche vend
|
||
|
||
**Il n'y a pas d'add-on casque.** Arbitré le 2026-08-31 (`vr-quest-unity-plan.md` §6), reconfirmé
|
||
ici parce que la question revient : un add-on « VR » ne se vendrait que le jour où l'app Unity existe
|
||
*et* où le client achète un casque. L'add-on **« Contenu immersif », 70 €/mois et plus**, vend la
|
||
couche 1 — qui s'affiche déjà en web, mobile et kiosk. Un client le souscrit et en a pour son argent
|
||
**sans casque**. Le casque est le haut de gamme de l'add-on, pas sa condition d'existence.
|
||
|
||
| Ce qui est vendu | Véhicule | Montant |
|
||
|---|---|---|
|
||
| Ressources immersives (360, GLB, POI) + l'app Quest quand elle sortira | add-on « Contenu immersif » | à partir de 70 €/mois, s'accroche à n'importe quel palier |
|
||
| Génération IA (images, puis props et scènes) | add-on Studio, crédits dédiés | voir `studio-plan.md` §3.5 |
|
||
| Casques | achat client | hardware |
|
||
| Provisioning, config borne, formation, journée sur site | onboarding one-shot | 1200-1500 €, **seulement s'il y a des casques** |
|
||
| Modélisation 3D d'atelier, photogrammétrie d'objets de collection | sur devis, hors Studio | 3 à 15 k€ |
|
||
|
||
### 2bis. Quota IA et crédits Studio — deux monnaies, et pourquoi
|
||
|
||
> **Arrêté le 2026-09-11.** La question « le Studio consomme-t-il le quota IA ? » revient à chaque
|
||
> conversation. Réponse : **non**, et voici le critère pour ne plus se la reposer.
|
||
|
||
**Le critère n'est pas « IA / pas IA ». C'est « consommé en temps réel par le visiteur » contre
|
||
« produit une fois par le client ».** Cette ligne décide du modèle de facturation parce qu'elle décide
|
||
de la forme de la courbe d'usage.
|
||
|
||
| | **Quota IA** | **Crédits Studio** |
|
||
|---|---|---|
|
||
| Unité | tokens / mois | crédits |
|
||
| Renouvellement | reset mensuel, non reporté | **rechargeables, expiration 12 mois** |
|
||
| Véhicule | attribut du palier | add-on |
|
||
| Courbe d'usage | récurrente, suit la fréquentation | **en pics** (préparation d'une expo) |
|
||
| Couvre | chat visiteur, canal vocal, traduction | images, 3D, scènes, vidéo, **TTS pré-généré** |
|
||
|
||
Le reset mensuel est **juste** pour le quota IA : l'usage suit la fréquentation, il est corrélé aux
|
||
vacances scolaires, et il est normal qu'il ne se reporte pas.
|
||
|
||
Il est **faux** pour le Studio. Un musée génère 200 images en trois semaines pour préparer une expo,
|
||
puis rien pendant cinq mois. Un forfait mensuel se gaspille dix mois sur douze : le client a le
|
||
sentiment de payer pour rien, et la capacité provisionnée ne sert pas.
|
||
|
||
➡️ **Correction à porter dans `studio-plan.md` §3.5** : `ImageCreditsMonthKey` et le
|
||
`Kind: MonthlyReset` deviennent inutiles. Le `CreditLedger` est déjà append-only avec un
|
||
`Kind: Grant` — il encaisse le modèle rechargeable **sans changement de schéma**. Gratuit à décider
|
||
maintenant, migration en prod plus tard.
|
||
|
||
**Le TTS pré-généré va côté Studio**, et c'est contre-intuitif puisque c'est « de l'IA ». Trois
|
||
raisons : il se facture au caractère et non au token, il produit un fichier (donc du stockage, comme
|
||
une image générée), et il se déclenche par pics quand le conservateur rédige. Le mettre sur le quota
|
||
tokens visiteur mélangerait deux courbes sans rapport.
|
||
|
||
**La traduction est le cas limite, laissé où il est.** Par le critère ci-dessus elle devrait être en
|
||
crédits Studio — déclenchée par le client, une fois, produisant un asset durable. Mais elle est déjà
|
||
sur le quota tokens, elle est très bon marché, et la déplacer ne rapporterait rien. Décision : **ne
|
||
pas y toucher**, mais le savoir plutôt que de le redécouvrir.
|
||
|
||
**Vérifié dans le code le 2026-09-11 — ce que le quota IA couvre réellement :**
|
||
|
||
| Endpoint | Débite le quota | Note |
|
||
|---|---|---|
|
||
| `POST /api/Ai/chat` | ✅ `AiController.cs:394` | |
|
||
| `POST /api/Ai/translate` | ✅ `AiController.cs:347` | |
|
||
| `POST /api/Ai/reindex/{instanceId}` | ❌ | **Les embeddings RAG coûtent et passent gratuitement** |
|
||
| `GET /api/Ai/insights/{instanceId}` | ❌ | idem |
|
||
|
||
⚠️ **Trou existant, indépendant du Studio** : deux endpoints facturés chez Google ne débitent rien.
|
||
Et `AiTokensPerMonth` vaut `0` en Essentiel et Pro, `20_000_000` en Premium
|
||
(`MyInfoMateDbContext.cs:607-637`) — donc le quota IA est aujourd'hui un **attribut du palier**, pas
|
||
un add-on. À ne pas confondre avec les crédits Studio, qui sont un add-on.
|
||
|
||
⚠️ **L'add-on immersif doit porter sa propre enveloppe de stockage, explicite et finie, avec
|
||
facturation du dépassement.** Un client Pro à 99 € a un quota dimensionné pour du Pro ; une vidéo 360
|
||
de 5 minutes pèse des Go, un monde exporté en splats aussi. Le principe est posé dans
|
||
`vr-quest-unity-plan.md` §6 — **il n'est toujours pas chiffré, et il doit l'être avant d'ouvrir la
|
||
couche 1 à la vente.**
|
||
|
||
---
|
||
|
||
## 3. Génération de scène 3D — état réel du marché
|
||
|
||
> **Révisé le 2026-09-11.** Une première passe de cette analyse concluait « ne pas faire, l'assemblage
|
||
> est la seule voie ». C'était fondé sur un état du marché périmé : la conclusion change, la limite
|
||
> qui la motivait reste vraie.
|
||
|
||
### Ce qui existe
|
||
|
||
[Marble](https://www.worldlabs.ai/blog/marble-world-model) (World Labs) génère des environnements 3D
|
||
persistants depuis du texte, une image, une vidéo ou un panorama, et **expose une World API depuis
|
||
janvier 2026** — à partir de **~0,12 $ le monde en draft**. Exports : splats (SPZ/PLY), panorama 360,
|
||
collider mesh basse résolution, et **mesh texturé GLB** sur le palier Pro, qui porte aussi les droits
|
||
commerciaux.
|
||
|
||
➡️ **Ça entre dans la couche fournisseur sans rien y changer** : un `GenerationModel` de plus en base,
|
||
`ProviderKey = "worldlabs"`, `Kind = Scene3D`. C'est exactement ce que `studio-plan.md` §3.6 a été
|
||
conçu pour absorber.
|
||
|
||
### La limite qui ne bouge pas
|
||
|
||
Un monde Marble est une **scène capturée**, excellente vue depuis et autour de son point de vue,
|
||
qui dégrade dès qu'on s'en éloigne. Chiffres rapportés côté Quest 3 standalone : plafond raisonnable
|
||
autour de **500k splats** (2M restant du domaine du VR filaire), environnements cadrés sur une grille
|
||
de ~10×10 m, et un cas mesuré à **12 fps sous Unity contre 19 dans le navigateur Oculus**. Une borne
|
||
publique doit tenir 72 fps, huit heures par jour, sans personne à côté.
|
||
|
||
Et il n'y a pas de sémantique : pas de sol identifié, pas d'objets nommés, pas d'interactions. Le
|
||
collider mesh fourni donne la collision, pas la compréhension de la scène.
|
||
|
||
### Position retenue
|
||
|
||
| Usage | Verdict |
|
||
|---|---|
|
||
| Fond immersif d'une visite ou du menu VR (le visiteur regarde autour de lui depuis un point fixe) | ✅ **oui**, c'est le cas d'usage nominal de la techno |
|
||
| Monde de référence en **roomscale stationnaire** : le visiteur est *dans* la scène, sur ~3 m | ✅ **oui** — et c'est mieux qu'un assemblage de props Meshy |
|
||
| Environnement navigable, le visiteur se déplace librement dedans | ❌ **non** en V2. Ni la perf en borne, ni la sémantique n'y sont |
|
||
| Props d'ambiance générés depuis du texte, placés sur ancres | ✅ **oui**, faible risque : un prop raté se jette |
|
||
|
||
**Le cadre retenu est le roomscale stationnaire, pas un diorama.** Arbitré le 2026-09-11 : une zone
|
||
d'environ 3 m où le visiteur tourne sur lui-même, se penche et tend le bras, mais ne se déplace pas.
|
||
C'est exactement la zone où Marble est bon — son point de capture — et où le budget de perf tient.
|
||
|
||
Ce n'est pas un pis-aller : la contrainte supprime d'un coup la locomotion, les collisions, le motion
|
||
sickness, la cohérence d'échelle au-delà du champ proche et l'essentiel du budget de perf. Et elle est
|
||
*meilleure* produit qu'un diorama vu de l'extérieur, parce que le visiteur est **dans** la scène.
|
||
Le but n'a jamais été de faire un jeu VR.
|
||
|
||
**Placement sur ancres prédéfinies, jamais libre.** Le template d'environnement Unity expose N
|
||
snap points ; le client y accroche ses props. Un éditeur de placement libre en 3D dans un back-office
|
||
web est un chantier à lui seul, pour un gain nul à ce stade.
|
||
|
||
### Image → GLB : mature en API, piégeux en produit
|
||
|
||
Meshy / Tripo / Rodin ont des API qui marchent, et le multi-vues améliore nettement le résultat. Mais
|
||
ce qui sort est un objet isolé, silhouette lisible, topologie sale, texture baked, échelle et pivot
|
||
arbitraires.
|
||
|
||
⚠️ **Pour un objet de collection, le problème n'est pas la qualité, c'est la véracité.** Un visiteur
|
||
qui fait tourner « le casque de Léon » croit voir l'objet. Deux conséquences :
|
||
|
||
- Sur un `Model3D` généré, la provenance visible est **obligatoire, non désactivable** — contrairement
|
||
aux images, où le badge suffit et la gravure est une option (`studio-plan.md` décision n°6).
|
||
- L'offre doit séparer explicitement **« objet numérisé »** (photogrammétrie, sur devis, hors Studio)
|
||
de **« illustration 3D »** (Studio). Les vendre sous le même mot est un risque réputationnel chez
|
||
une institution scientifique.
|
||
|
||
### Le vrai sur-scope : l'éditeur, pas la génération
|
||
|
||
`vr-quest-unity-plan.md` §9 signale l'éditeur de placement de POI comme « le seul morceau non
|
||
trivial ». Il le sous-estime : **Flutter web n'a pas de stack 3D éditable.** `model_viewer_plus` est
|
||
une WebView autour de `<model-viewer>`, en lecture seule.
|
||
|
||
➡️ **Décision à prendre maintenant, parce qu'elle conditionne tout le chiffrage** : l'éditeur de POI
|
||
3D est une **page three.js embarquée en iframe**, pas un widget Flutter. Précédent dans le repo : la
|
||
démo villa d'Echternach (`visitapp-web/src/app/demo/villa-echternach/scene.ts`).
|
||
|
||
---
|
||
|
||
## 4. `ImmersiveBackground` — un type, deux porteurs
|
||
|
||
`Configuration` porte aujourd'hui `ImageId` et `LoaderImageId`, rien d'immersif. Poser un
|
||
`Configuration.BackgroundResourceId` à plat, puis un autre champ sur l'`ApplicationInstance`, puis un
|
||
troisième pour la scène, donne quatre champs « background » incohérents dans six mois.
|
||
|
||
```
|
||
ImmersiveBackground
|
||
ResourceId
|
||
Kind -- Pano | Video360 | Scene3D
|
||
FallbackResourceId? -- 2D, pour les canaux qui ne savent pas rendre
|
||
```
|
||
|
||
Porté par **`Configuration`** (le fond d'une visite) **et** par l'**`ApplicationInstance` VR** (le
|
||
fond du menu général — l'équivalent de home v3 côté mobile). Un seul type, deux porteurs, pas deux
|
||
modèles.
|
||
|
||
**Dégradation par canal, écrite dans le contrat** — sinon les fonds casseront silencieusement :
|
||
|
||
| Canal | `Pano` | `Video360` | `Scene3D` |
|
||
|---|---|---|---|
|
||
| VR (Quest) | rendu | rendu | rendu |
|
||
| Web | visite pivotante | visite pivotante | fallback 2D |
|
||
| Mobile | fallback 2D | fallback 2D | fallback 2D |
|
||
| Kiosk | fallback 2D | fallback 2D | fallback 2D |
|
||
|
||
Chaque canal déclare ce qu'il sait rendre ; le fallback est `Configuration.ImageId` par défaut.
|
||
|
||
---
|
||
|
||
## 5. Décisions de rétro-compatibilité, du plus cher au moins cher
|
||
|
||
Les points **1 à 5 doivent être écrits dans `studio-plan.md` avant sa première migration.** Les
|
||
suivants peuvent s'écrire au fil de l'eau.
|
||
|
||
### 1. Pipeline d'ingestion unique côté serveur
|
||
|
||
**Le trou le plus cher, et il est structurel, pas accidentel.** Aujourd'hui **l'upload est fait par
|
||
le navigateur en direct** (`resources_screen.dart:247-256`) ; le backend ne sait que supprimer
|
||
(`IResourceBlobService.DeleteAsync`). Le Studio, lui, produit côté serveur et post-traite **à la
|
||
validation d'un brouillon**.
|
||
|
||
➡️ Un GLB **uploadé** ne traverserait aucun traitement, un GLB **généré** traverserait le chemin
|
||
Studio. Deux chemins par construction.
|
||
|
||
- [ ] Déplacer le point de passage de « validation d'un asset Studio » à **« ingestion de tout asset,
|
||
quelle que soit sa provenance »**
|
||
- [ ] Un seul service de post-traitement, appelé par les deux chemins
|
||
- [ ] Le lot 0 (`UploadAsync`, `CopyAsync`, `ProbeSizeAsync`) est le prérequis mais **ne suffit pas**
|
||
|
||
Coût du retrofit : l'upload navigateur direct est partout dans manager-app, et il faudrait retraiter
|
||
la base d'assets existante.
|
||
|
||
### 2. Normalisation canonique des GLB
|
||
|
||
- [ ] Pivot recentré, échelle normalisée, up-axis fixé — **déterministes**
|
||
- [ ] Budgets de validation (tris, taille de texture, poids) : **rejet**, pas réparation
|
||
- [ ] Draco + KTX2 dans le même passage
|
||
- [ ] `Model3DVersion` sur la ressource
|
||
|
||
Coût du retrofit : **tout POI posé avant est perdu.** C'est ce qui rend ce point non négociable, pas
|
||
l'élégance du pipeline.
|
||
|
||
### 3. Invalidation et repositionnement des POI
|
||
|
||
Absent des deux plans. Et c'est structurellement plus grave qu'en géo : une lat/lon survit à un
|
||
changement de fond de carte, un (x,y,z) local est **détruit** par un changement de pivot, d'échelle ou
|
||
d'up-axis.
|
||
|
||
- [ ] POI attachés à `(resourceId, modelVersion)`
|
||
- [ ] Au remplacement ou à la régénération : POI **conservés et marqués « à revalider »**, jamais
|
||
supprimés en silence
|
||
- [ ] Écran de repositionnement dans l'éditeur
|
||
|
||
Peu de code si pris tôt. Coûteux en confiance client si découvert en prod.
|
||
|
||
### 4. Lignage en colonnes typées
|
||
|
||
`Resource.AiProvenance` (jsonb) distingue uploadé (null) de généré (non-null) et liste des
|
||
`referenceResourceIds[]`. **Mais un tableau dans un jsonb n'est pas un lignage requêtable**, et rien
|
||
ne couvre un GLB **dérivé** — reprocessé, décimé, regénéré depuis le même jeu de photos.
|
||
|
||
- [ ] `Resource.Origin` : `Uploaded | Generated | Derived` — **colonne**, pas jsonb
|
||
- [ ] `Resource.SourceResourceId` nullable — le lignage parent/enfant
|
||
- [ ] `AiProvenance` reste pour le détail (prompt effectif, seed, version d'identité)
|
||
|
||
Coût du retrofit : migration de données sur des assets déjà en base.
|
||
|
||
### 5. Renommer la monnaie de crédits — ✅ **porté dans `studio-plan.md` le 2026-09-11**
|
||
|
||
`ImageCreditsPerMonth`, `ImageCreditsThisMonth`, `ImageCreditsMonthKey`, `ImageCreditsHardCap`,
|
||
`SubscriptionPlan.ImageCreditsPerMonth`. Or une 3D coûte 10 à 50 fois une image, et un monde Marble
|
||
n'est pas une image du tout.
|
||
|
||
- [x] `ImageCredits*` → **`StudioCredits*`** partout
|
||
- [x] `GenerationModel.CreditCost` déjà par modèle : rien d'autre à faire côté tarification
|
||
- [x] **Et le modèle change aussi** : crédits **rechargeables à expiration 12 mois** au lieu d'un
|
||
quota mensuel. Un musée génère en pics, pas linéairement — un forfait mensuel se gaspille dix
|
||
mois sur douze. Voir `studio-plan.md` §3.5 et le §2bis ci-dessus
|
||
|
||
**Gratuit aujourd'hui. Migration de colonnes en prod plus tard.** Le retrofit le moins cher à éviter
|
||
et le plus bête à subir. ➡️ **Fait** : décision n°3 du tableau §2, bloc §3.5, schéma §5 et lot 1 de
|
||
`studio-plan.md` sont à jour. Reste ouvert : le mapping Stripe `checkout.session.completed` →
|
||
`Kind: Grant` pour la recharge.
|
||
|
||
### 6. Contrat fournisseur : multi-fichier et par kind
|
||
|
||
`ProviderResult` est pensé mono-fichier image. Une génération 3D retourne GLB + preview + parfois
|
||
textures séparées ; un monde retourne splat + collider mesh + panorama.
|
||
|
||
- [ ] `ProviderResult` multi-fichier
|
||
- [ ] `GenerationKind` += `Model3D`, `SceneProp`, `Scene3D`
|
||
- [ ] **Timeout et politique de retry par kind** — le `PollFallback` à +90 s et le polling front à 2 s
|
||
de `studio-plan.md` §3.7 sont dimensionnés pour un job image de 20-60 s
|
||
- [ ] **Job composite** : générer 8 props est un job parent + N enfants, pas un job
|
||
|
||
### 7. `ImmersiveBackground` comme type réutilisable
|
||
|
||
Voir §4. Deux porteurs, un type, dégradation par canal dans le contrat.
|
||
|
||
### 8. Les trois valeurs `ResourceType` d'un coup
|
||
|
||
Voir §1, couche 1.
|
||
|
||
### 9. Éditeur 3D = iframe three.js
|
||
|
||
Décision d'architecture, pas d'implémentation. Voir §3.
|
||
|
||
### 10. Chiffrer l'enveloppe de stockage de l'add-on immersif
|
||
|
||
Voir §2. Posé en principe le 31/08, jamais chiffré.
|
||
|
||
### 11. Provenance obligatoire sur un `Model3D` généré
|
||
|
||
Voir §3. Et séparer « objet numérisé » de « illustration 3D » dans l'offre.
|
||
|
||
---
|
||
|
||
## 6. Droits et modération — ce qui reste ouvert
|
||
|
||
Couvert par `studio-plan.md` : `rightsHolder` = l'instance (les droits sont au client, écrit dans la
|
||
donnée), provenance complète, badge visiteur traduit dans les langues de la configuration, et la
|
||
redirection des personnes identifiables vers les personnages.
|
||
|
||
**Pas couvert, et spécifique à la 3D** : rien sur les objets dont le client **n'a pas** les droits —
|
||
prêts, dépôts, collections tierces. C'est le quotidien d'un musée, et générer un GLB depuis la photo
|
||
d'un objet en dépôt n'est pas anodin.
|
||
|
||
➡️ Traitement retenu : **CGU + une mention explicite dans l'écran de génération 3D**, pas de
|
||
vérification automatique. Pas de modération automatique entrée/sortie non plus. Acceptable au stade
|
||
pilote — **à condition de l'assumer par écrit**, pas de le découvrir.
|
||
|
||
---
|
||
|
||
## 7. Chemin critique
|
||
|
||
Ce n'est pas celui qu'on croit. La génération 3D est en toute fin, et c'est la brique la **moins**
|
||
risquée de la liste, parce qu'à ce stade tout ce qui la consomme existe et est validé.
|
||
|
||
```
|
||
Lot 0 — socle de stockage serveur (prérequis dur, sert aussi le TTS)
|
||
└─ + pipeline d'ingestion unique (décision n°1)
|
||
└─ Ressource 360° (le plus petit des trois chantiers médias)
|
||
└─ SectionModel3D + POI (GeoPoint réutilisé à 80 %)
|
||
└─ Back-office XR (8-12 j, se tient debout tout seul)
|
||
└─ Studio images (lots 1 à 6)
|
||
└─ ⛔ GATE lot 4 : un conservateur, 10 images, seul
|
||
└─ Studio 3D + scènes
|
||
└─ App Unity (go/no-go client pilote)
|
||
```
|
||
|
||
Le go/no-go de l'app Unity reste conditionné à **un client pilote disposant déjà de contenu immersif**
|
||
— et la couche 1 rend cette condition atteignable, puisqu'elle permet au client de *fabriquer* ce
|
||
contenu au lieu de devoir le posséder d'avance. C'est le changement le plus important qu'apporte le
|
||
Studio au dossier XR.
|
||
|
||
---
|
||
|
||
## 8. Ce qu'on ne fait pas
|
||
|
||
- **Environnement VR navigable** en V2 — roomscale stationnaire ~3 m seulement (§3)
|
||
- **Placement libre de props** — ancres prédéfinies
|
||
- **Locomotion en VR** — le visiteur tourne sur lui-même, il ne marche pas
|
||
- **Les mécaniques de jeu du §9** — notées, pas planifiées
|
||
- **Photogrammétrie / fac-similé d'objets de collection** — sur devis, hors Studio
|
||
- **Modération automatique** entrée/sortie — CGU + provenance + `rightsHolder` (§6)
|
||
- **Retopologie ou upscaling automatique** — budgets de validation et rejet, pas de réparation
|
||
- **Refonte du routing de manager-app** — les deux `switch` numérotés en dur de `main_screen.dart`
|
||
sont acceptés tels quels, comme dans `studio-plan.md`
|
||
|
||
---
|
||
|
||
## 9. Mécaniques de jeu immersives — 📝 idées notées, rien de planifié
|
||
|
||
> **Noté le 2026-09-11, à la suite du canal VR — pas dans son périmètre.** Aucune de ces mécaniques
|
||
> n'est chiffrée ni engagée. Elles sont ici pour ne pas être reperdues, et parce que **deux d'entre
|
||
> elles réutilisent des données qui existent déjà**, ce qui change leur coût relatif.
|
||
|
||
**Le principe structurant, à ne pas perdre** : un jeu configurable par le client **n'est pas un
|
||
moteur de jeu, c'est un type de section**. Trois mécaniques génériques couvrent l'essentiel de ce qui
|
||
a du sens en musée, et toutes tiennent dans les ~3 m du roomscale stationnaire. Le client compose ;
|
||
un vrai jeu sur mesure reste un devis.
|
||
|
||
| Mécanique | Ce que c'est | Données | Coût |
|
||
|---|---|---|---|
|
||
| **Répondre** | Quiz immersif : question devant, réponses sur 3-4 panneaux autour, réponse au regard ou à la main. Fond = `ImmersiveBackground` de la configuration | **`SectionQuiz`, déjà là** | rendu seul, **config nulle** |
|
||
| **Trouver** | Chasse aux détails dans un pano 360 : « trouve les 5 détails », « repère les 3 erreurs ». Le client pose des hotspots | même geste que poser des POI → **le même éditeur iframe sert deux fois** | faible, et **ça marche aussi en web** sur pano pivotant → se vend sans casque |
|
||
| **Ordonner** | Tri chronologique ou logique : attraper des objets autour de soi et les ranger. Frise, étapes d'un procédé | **`OrderedTranslationAndResource`, déjà dans le modèle** | faible, config = une liste ordonnée |
|
||
| **Avant / après** | « À quoi ressemblait cette place en 1900 ? » — le visiteur devine, puis bascule | **`BeforeAfterPairs`** du lot 9 du Studio | rendu seul |
|
||
|
||
**Le meilleur rapport valeur/effort est « Répondre »** : `SectionQuiz` est déjà configuré par les
|
||
clients aujourd'hui. Le jeu, c'est le rendu — zéro donnée nouvelle, zéro apprentissage côté client.
|
||
|
||
**Le plus intéressant commercialement est « Trouver »**, pour une raison qui n'a rien à voir avec la
|
||
VR : il fonctionne sur un pano 2D pivotant en web. Une mécanique de jeu qui se vend **sans casque**,
|
||
sur l'add-on immersif seul.
|
||
|
||
**Écarté, et pourquoi :**
|
||
|
||
| Idée | Pourquoi non |
|
||
|---|---|
|
||
| Remontage d'objet (amphore à reconstituer) | Effet musée énorme, mais il faut un GLB **pré-découpé en pièces**. Le client ne peut pas le produire seul → casse la règle d'autonomie. **Sur devis uniquement** |
|
||
| Escape game VR | La logique conditionnelle n'est pas configurable en trois champs. L'escape game reste sur le canal mobile, où il fonctionne déjà |
|
||
| Tir, action, visée | Hors sujet produit |
|
||
| Dialogue avec un PNJ scripté | Le guide IA le fait déjà mieux, et sans script à maintenir |
|
||
| Tout ce qui demande de marcher | Contredit le roomscale stationnaire (§3) |
|
||
|
||
---
|
||
|
||
## 10. Ce que ce document change dans les deux autres plans
|
||
|
||
| Plan | À reprendre |
|
||
|---|---|
|
||
| `studio-plan.md` | Le **lot 11 (3D)** passe de quatre lignes à un lot réel : `Scene3D` comme `GenerationKind`, World Labs dans le catalogue, provenance obligatoire sur `Model3D`. Les décisions n°1, 4, 5 et 6 du §5 ci-dessus touchent des lots **antérieurs** (lot 0, lot 1, lot 3) et doivent y être écrites. |
|
||
| `vr-quest-unity-plan.md` | Le **§9 (POI sur GLB)** gagne la version de modèle, l'invalidation des POI et la décision « éditeur en iframe three.js ». Le **§6 (pricing)** gagne l'enveloppe de stockage chiffrée. Le §2 lot V-4 gagne `ImmersiveBackground` comme source du fond de scène. |
|
||
| `todo-features.md` | La « Ressource 360° » devient les **trois** valeurs d'enum, en une migration. |
|
||
| Kanban | Les cartes 250, 280, 300, 320 et 330 restent valides. Ce document est la source à citer en `src:` pour la frontière. |
|