Navigation
Le module Navigation permet au Inverse3 de déplacer l'espace de travail de l'application — ce que l'on appelle parfois « locomotion à contrôle de vitesse » ou « dérive de type manette de jeu ». Au lieu de heurter un mur rigide au bord de l'espace de travail physique, le curseur pénètre dans une enveloppe souple où sa distance par rapport à un centre virtuel est convertie en une vitesse qui fait glisser l'ensemble de l'espace de travail. Plus le curseur avance, plus la scène défile rapidement.
Le principal (et pour l'instant unique) mode de navigation est la navigation par bulles. La forme de la bulle est définie à l'aide d'une primitive SDF — voir « Qu'est-ce qu'un SDF ? » pour en savoir plus sur ce concept.
Navigation par bulles — concept
Une bulle virtuelle est centrée sur un point situé dans l'espace de montage de l'appareil. Le curseur passe par trois zones concentriques :
┌──────────────────────────────────────────┐
│ WALL ZONE │ cursor beyond outer shell
│ ┌────────────────────────────────────┐ │
│ │ VELOCITY ZONE │ │ soft shell → scene moves
│ │ ┌──────────────────────────────┐ │ │
│ │ │ DEAD ZONE (inside) │ │ │ no scene movement
│ │ │ │ │ │
│ │ │ ● centre │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────┘ │ │
│ │ bubble surface │ │
│ └────────────────────────────────────┘ │
│ outer boundary │
└──────────────────────────────────────────┘
| Zone | Position du curseur | Comportement |
|---|---|---|
| Zone morte | À l'intérieur de la bulle | Pas de navigation. Atténuation de la lumière. Vous pouvez manipuler librement la scène. |
| Zone de vitesse | Entre la surface et la limite extérieure | La courbe « Distance → vitesse » déplace l'espace de travail dans la direction du curseur. |
| Zone murale | Au-delà de la limite extérieure | Un ressort rigide repousse le curseur vers l'intérieur et la vitesse de déplacement atteint son maximum. |
Une force haptique générée par un ressort-amortisseur est appliquée sur les trois zones : vous sentez la surface, la coque de glissement et la paroi extérieure.
Guide de démarrage rapide — Activer la navigation par bulles
La navigation est une configuration permanente et unique : une fois envoyée, elle reste active jusqu'à ce que vous l'arrêtiez explicitement, que vous redémarriez le service ou que vous fermiez la session.
Démarrer (minimal — bulle avec cadre arrondi par défaut)
- WebSocket
- HTTP
{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "bubble" }
}
}
]
}
curl -X POST "http://localhost:10001/inverse3/04C3/config/navigation?session=:0" \
-H "Content-Type: application/json" \
-d '{"mode": "bubble"}'
Arrêter
- WebSocket
- HTTP
{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "disabled" }
}
}
]
}
curl -X DELETE "http://localhost:10001/inverse3/04C3/config/navigation?session=:0"
Autres routes HTTP
| Méthode | Chemin | Objectif |
|---|---|---|
GET | /{type}/{id}/config/navigation?session=<expr> | Configuration et état actuels de la navigation |
POST | /{type}/{id}/config/navigation?session=<expr> | Lancer ou mettre à jour la navigation |
DELETE | /{type}/{id}/config/navigation?session=<expr> | Arrêter la navigation |
Catalogue des formes de bulles
La zone morte de la bulle est définie par une forme de fonction de distance signée (SDF). Chaque forme offre une expérience de navigation différente : un parallélépipède arrondi (par défaut) pour une zone de repos rectangulaire confortable, une sphère pour une dérive isotrope, un ellipsoïde pour privilégier certains axes, une capsule pour les couloirs.
Boîte arrondie (par défaut)
La zone morte par défaut est un volume plat, légèrement plus haut que profond, réglé pour offrir un confort optimal aussi bien sur Inverse3 sur MInverse:
{
"shape": {
"primitive": "rounded_box",
"parameters": { "b": { "x": 0.05, "y": 0.02, "z": 0.03 }, "r": 0.01 }
}
}
Sphère — dérive isotrope
{
"shape": {
"primitive": "sphere",
"parameters": { "r": 0.05 }
}
}
Ellipsoïde — plus large dans les axes X et Z que dans l'axe Y
À utiliser lorsque le glissement horizontal doit sembler plus souple que le glissement vertical :
{
"shape": {
"primitive": "ellipsoid",
"parameters": { "a": { "x": 0.06, "y": 0.03, "z": 0.06 } }
}
}
Capsule — couloir allongé
Deux points d'arrivée a/b plus un rayon r:
{
"shape": {
"primitive": "capsule",
"parameters": {
"a": { "x": 0.0, "y": -0.03, "z": 0.0 },
"b": { "x": 0.0, "y": 0.03, "z": 0.0 },
"r": 0.04
}
}
}
Exemple complet avec dimensions personnalisées et sensation de mouvement :
{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": {
"mode": "bubble",
"bubble": {
"shape": {
"primitive": "ellipsoid",
"parameters": { "a": { "x": 0.06, "y": 0.03, "z": 0.06 } }
},
"velocity_zone_width": 0.025,
"max_velocity": 1.0,
"velocity_ease": "quadratic_in"
}
}
}
}
]
}
Courbe de vitesse
La distance de la zone de vitesse est convertie à l'aide d'une courbe d'accélération avant d'être transformée en vitesse dans l'espace de travail. Choisissez l'accélération qui correspond à la manière dont vous souhaitez que la scène s'accélère à mesure que l'utilisateur s'enfonce davantage dans la coque.
velocity_ease | Ressentir | Quand l'utiliser |
|---|---|---|
linear | Rampe constante | Prévisible, un bon choix par défaut |
quadratic_in | Un démarrage lent, puis une accélération | Précis près de la surface, rapide sur de longues distances |
cubic_in | Un démarrage très lent | Très précis, course longue, accélération progressive |
sine_out | Démarrage rapide et en douceur, plateau vers l'extérieur | Réactif, majuscules en douceur |
quadratic_out | Rapide au démarrage, confortable sur les longues distances | Accélération vive, conduite confortable |
{ "velocity_ease": "quadratic_in", "max_velocity": 1.5 }
Comportement au centre
Le centre de la bulle est défini par une structure imbriquée center objet comportant quatre
champs — position, relative, follow, speed — en remplacement de l'ancienne disposition
à plat composée de center, center_enabled, center_modeet center_drift_speed.
{
"center": {
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"relative": true,
"follow": false,
"speed": 0.02
}
}
Là où le centre est ancré
position et relative définir l'emplacement initial du centre lors de l'activation :
relative | Sémantique de position |
|---|---|
true (par défaut) | position est un décalage par rapport au curseur — le centre initial est cursor + position. Avec la valeur par défaut (0, 0, 0), la bulle apparaît exactement à l'endroit où se trouve le curseur. |
false | position est un point absolu dans l'espace de l'application — il est converti en espace de montage à l'entrée, puis reconverti en espace d'application à la sortie, de sorte que les valeurs aller-retour correspondent. |
Comment le centre évolue par la suite
follow et speed contrôler le comportement à chaque tick une fois que la bulle est active :
follow | speed | Comportement | Équivalent précédent |
|---|---|---|---|
false (par défaut) | ignoré | Le centre reste à l'endroit où il a été défini — centre fixe. | center_mode: "fixed" |
true | > 0 | Le centre se déplace vers le curseur à speed m/s tant que le curseur se trouve à l'intérieur. | center_mode: "auto_follow" (avec center_drift_speed) |
true | 0.0 | Le centre s'aligne sur le curseur à chaque pas — on a l'impression de se téléporter. | center_mode: "track_cursor" |
Le comportement par défaut du centre est désormais corrigé (follow = false). Les versions antérieures
se déplaçaient par défaut vers le curseur (auto_follow). Définir center.follow = true
pour rétablir l'ancien comportement de dérive et affiner center.speed pour correspondre à l'ancienne valeur
de center_drift_speed.
Quand follow = true et lorsque le curseur dépasse la limite extérieure, le centre
suit le curseur, quelle que soit speed, afin de conserver la bulle autour et
d'empêcher le curseur de s'échapper.
Réaction en cas de collision
La bulle réagit aux forces externes exercées par le curseur qui dépassent collision_detection.force_threshold:
- La zone de vitesse temporaire gonfle (jusqu'à
collision_detection.inflate_ratiofoisvelocity_zone_width) afin de laisser à l'utilisateur davantage de marge de manœuvre pour contourner l'obstacle. - Quand
collision_detection.enabledesttrue(par défaut), le centre de la bulle refuse de se déplacer dans la direction de la force de collision, empêchant ainsi l'utilisateur de faire glisser l'espace de travail contre un mur solide.
Utilisations de la détection de collision hystérésis pour éviter les effets de scintillement autour du seuil :
une fois qu'une collision est active, elle le reste jusqu'à ce que |ext_force| tombe en dessous du
produit collision_detection.force_threshold × collision_detection.exit_ratio.
Abaissez le exit_ratio pour élargir la bande d'hystérésis (collisions plus adhérentes) ; réglez-la
sur 1.0 pour désactiver l'hystérésis et utiliser un seul seuil.
{
"collision_detection": {
"enabled": true,
"force_threshold": 0.5,
"inflate_ratio": 2.0,
"exit_ratio": 0.7
}
}
Référence des paramètres
Les plus fréquemment réglés
| Paramètres | Par défaut | Description |
|---|---|---|
shape | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | SDF définissant la zone morte |
velocity_zone_width | 0.03 m | Épaisseur de la coque de régulation de débit |
max_velocity | 0.5 m/s | Vitesse maximale de navigation |
velocity_ease | "quadratic_in" | Courbe d'accélération de la vitesse en fonction de la distance |
center.follow | false | Le centre suit-il le curseur ? |
center.speed | 0.02 m/s | Vitesse de dérive lorsque follow = true |
Liste complète des paramètres
| Champ d'application | Type | Par défaut | Description |
|---|---|---|---|
center.position | vec3 | (0, 0, 0) | Point de départ — décalage du curseur lorsque relative = true, point absolu dans l'espace de l'application lorsque false |
center.relative | bool | true | true: position correspond à un décalage par rapport au curseur. false: point absolu dans l'espace de l'application, converti en espace de montage à la limite |
center.follow | bool | false | false: le centre reste fixe dans sa position initiale. true: le curseur reste centré |
center.speed | float | 0.02 | Vitesse de dérive (m/s) lorsque follow = true; 0.0 s'aligne sur le curseur à chaque tick |
shape | forme | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | Forme SDF de la zone morte |
velocity_zone_width | float | 0.03 | Largeur de la coque de régulation de débit (m) |
max_velocity | float | 0.5 | Vitesse maximale de navigation (m/s) |
velocity_ease | chaîne de caractères | "quadratic_in" | Accélération progressive de la vitesse en fonction de la distance |
reset_velocity_on_entry | bool | true | Remettre à zéro la vitesse cumulée lorsque le curseur repasse dans la zone de vitesse |
bump_width | float | 0.005 | Relief tactile à la surface (m) |
bump_stiffness | float | 200.0 | Constante de rappel de la surface |
spring_inner | float | 0.0 | Le printemps au centre de la bulle |
spring_surface | float | 10.0 | Le printemps à la surface |
spring_outer | float | 15.0 | Le printemps aux confins |
wall_stiffness | float | 700.0 | Ressort à paroi rigide dépassant la limite extérieure |
damping_inner | float | 0.1 | Amortissement au centre |
damping_surface | float | 4.0 | Amortissement en surface |
damping_outer | float | 7.0 | Amortissement à la limite extérieure |
rotation_enabled | bool | false | Appliquer la rotation de l'espace de travail à la direction de navigation |
scale_enabled | bool | false | Appliquer l'échelle de l'espace de travail à la vitesse de navigation |
collision_detection.enabled | bool | true | Bloquer la navigation dans la direction de la collision |
collision_detection.force_threshold | float | 1.0 | Intensité de la force externe à saisir pour une collision (N) |
collision_detection.inflate_ratio | float | 2.0 | Multiplicateur de la largeur de la zone de vitesse lors d'une collision (doit être ≥ 1,0) |
collision_detection.exit_ratio | float | 0.7 | Rapport d'hystérésis — rester en collision jusqu'à ce que |ext_force| < force_threshold × exit_ratio. Gamme (0, 1]; 1.0 désactive l'hystérésis |
Deux groupes de fonctionnalités ont été supprimés du schéma JSON 3.5, tandis que leurs implémentations ont été remaniées pour la version 3.6 :
- Limitation des limites de l'avatar: les champs
avatar_boundary_enabled,avatar_boundaryetavatar_boundary_hysteresis. - Délimitation de l'espace de travail: les champs
workspace_bounded,workspace_transition_speedetworkspace_transition_ease.
Le code du tick se compile et s'exécute toujours avec les paramètres par défaut, mais les clients ne peuvent ni lire ni
écrire dans ces champs via HTTP ou WebSocket. Dans la version 3.6, la limite de l'avatar
sera renvoyée en tant que variable de premier niveau bounds un équivalent de l'objet « bubble » avec une transformation de placement complète ;
la délimitation de l'espace de travail sera rétablie dès que l'étude sur le « centre-jitter »
aura abouti.
Règles de validation
velocity_zone_width > 00 ≤ bump_width < velocity_zone_widthmax_velocity > 0bump_stiffness ≥ 0spring_inner ≥ 0etspring_inner ≤ spring_surface ≤ spring_outerwall_stiffness ≥ 0damping_inner ≥ 0etdamping_inner ≤ damping_surface ≤ damping_outercollision_detection.force_threshold > 0collision_detection.inflate_ratio ≥ 1.0collision_detection.exit_ratiodans(0, 1]center.speed ≥ 0
A POST ou configure.navigation avec des paramètres non valides est rejetée et une
invalid-value l'événement est déclenché ; la configuration précédente reste active.
Evénements
| Nom de l'événement | Licencié lorsque |
|---|---|
navigation-started | La navigation est activée sur l'appareil |
navigation-updated | La configuration de la navigation est mise à jour alors qu'elle est déjà active |
navigation-stopped | La navigation est désactivée (désactivation explicite, DELETE, ou à la fin de la session) |
invalid-value | Une configuration de navigation est rejetée lors de la validation |
Limites connues
- Masquage des limites de l'espace de travail et des contours de l'avatar dans la version 3.5: ces deux groupes de fonctionnalités sont absents du schéma JSON, mais ils ont été remaniés pour la version 3.6. Voir la remarque ci-dessus dans la section « Référence des paramètres ».
- Échelle non uniforme + rotation: lorsque les deux
rotation_enabledetscale_enabledlorsqu'elles sont activées, la direction de la vitesse est légèrement imprécise — la rotation n'est pas appliquée aux axes de l'échelle. - Mise à l'échelle par appareil: les dimensions des bulles (rayon, largeur de la zone) ne sont pas mises à l'échelle en fonction du facteur d'échelle physique de l'appareil — MInverse Inverse3 les mêmes dimensions absolues, ce qui peut donner une impression différente sur chaque appareil.