Aller au contenu principal

Navigation

Le module Navigation permet à un curseur 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 à la manette de jeu ». Plutôt que de heurter une paroi rigide à la limite de l'espace de travail physique, le curseur pénètre dans une enveloppe souple où sa distance par rapport à un centre virtuel est associée à une vitesse qui fait glisser l'ensemble de l'espace de travail. Plus le curseur est poussé loin, plus la scène défile vite.

Le principal mode de navigation(et actuellement le seul) est la navigation par bulle. 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 bulle — concept​

Une bulle virtuelle est centrée sur un point précis dans l'espace de montage du dispositif. Le curseur se déplace au sein de 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 │
└──────────────────────────────────────────┘
ZonePosition du curseurComportement
Zone morteÀ l'intérieur de la bullePas de navigation. Amortissement léger. Vous pouvez manipuler la scène comme bon vous semble.
Zone de vitesseEntre la surface et la limite extérieureLa courbe distance → vitesse déplace l'espace de travail dans la direction du curseur.
Zone de paroiAu-delà de la frontière extérieureUn ressort rigide repousse le curseur vers l'intérieur, ce qui limite la vitesse de déplacement.

Une force haptique de type ressort-amortisseur s'exerce dans les trois zones : vous percevez la surface, la coque de la dérive et la paroi extérieure.


Guide de démarrage rapide — activer la navigation par bulles​

La navigation est une configuration persistante, envoyée en une seule fois : elle reste active jusqu'à ce que vous la désactiviez explicitement, que vous redémarriez le service ou que vous vous déconnectiez.

Démarrer (version minimale — bulle par défaut dans une boîte arrondie)​

{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "bubble" }
}
}
]
}

Arrêter​

{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "disabled" }
}
}
]
}

Autres routes HTTP​

MéthodeCheminRôle
GET/{type}/{id}/config/navigation?session=<expr>Configuration actuelle de la navigation et état
POST/{type}/{id}/config/navigation?session=<expr>Lancer ou actualiser 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 à fonction de distance signée (SDF). Différentes formes procurent des sensations de navigation variées : une boîte arrondie (valeur 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, configuré pour offrir un confort d'utilisation optimal aussi bien sur Inverse3 que 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 grand dans les axes X et Z que dans l'axe Y​

À utiliser lorsque la dérive horizontale doit être plus souple que la dérive verticale :

{
"shape": {
"primitive": "ellipsoid",
"parameters": { "a": { "x": 0.06, "y": 0.03, "z": 0.06 } }
}
}

Capsule — couloir allongé​

Deux points d'extrémité a/b ainsi qu'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 dimensionnement personnalisé et impression 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 transformée par une courbe d'accélération (easing) avant d'être convertie 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 lorsque l'utilisateur appuie davantage sur la coque.

velocity_easeSensationQuand l'utiliser
linearPente constantePrévisible, bon choix par défaut
quadratic_inDépart lent, accélération plus rapidePrécis près de la surface, long trajet rapide
cubic_inDépart très lentTrès précis, ils prennent de la vitesse sur les longs trajets
sine_outDépart rapide et fluide, plateau près de l'extérieurRéactif, atteint son plafond en douceur
quadratic_outRapide au démarrage, confortable sur les longs trajetsUne petite accélération rapide, une conduite confortable
{ "velocity_ease": "quadratic_in", "max_velocity": 1.5 }

Comportement du centre​

Le centre de la bulle est défini à l'aide d'un objet imbriqué center comportant quatre champs — position, relative, follow, speed — qui remplace l'ancienne disposition à plat composée de center, center_enabled, center_mode et center_drift_speed.

{
"center": {
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"relative": true,
"follow": false,
"speed": 0.02
}
}

Ancrage du centre​

position et relative déterminent la position initiale du centre lors de l'activation :

relativeSé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 sur le curseur.
falseposition est un point absolu dans l'espace de l'application — il est converti en espace de montage à l'entrée, puis reconverti en espace de l'application à la sortie, de sorte que les valeurs après un aller-retour correspondent.

Déplacement ultérieur du centre​

follow et speed contrôlent le comportement à chaque cycle une fois que la bulle est active :

followspeedComportementÉquivalent précédent
false (par défaut)ignoréLe centre reste à sa position initiale — centre fixe.center_mode: "fixed"
true> 0Le centre se déplace vers le curseur à la vitesse speed (m/s) tant que le curseur se trouve à l'intérieur.center_mode: "auto_follow" (avec center_drift_speed)
true0.0Le centre se positionne sur le curseur à chaque cycle — effet de téléportation.center_mode: "track_cursor"
Valeur par défaut modifiée dans la version 3.5

Le comportement par défaut du centre est désormais fixe (follow = false). Les versions antérieures utilisaient le curseur par défaut (auto_follow). Définissez center.follow = true pour rétablir l'ancien comportement de dérive, puis réglez center.speed pour correspondre à l'ancienne valeur de center_drift_speed.

Lorsque follow = true et dès que le curseur dépasse la limite extérieure, le centre suit le curseur quelle que soit la valeur de speed, afin de maintenir la bulle autour de lui et d'empêcher le curseur de s'échapper.


Réaction en cas de collision​

La bulle réagit aux forces externes exercées sur le curseur qui dépassent collision_detection.force_threshold :

  • La zone de vitesse s'élargit temporairement (jusqu'à collision_detection.inflate_ratio fois velocity_zone_width) afin de donner à l'utilisateur davantage de marge de manœuvre pour contourner l'obstacle.
  • Lorsque collision_detection.enabled vaut true (par défaut), le centre de la bulle refuse de dériver dans la direction de la force de collision, ce qui empêche l'utilisateur de faire glisser l'espace de travail contre un mur rigide.

La détection des collisions utilise l'hystérésis pour éviter le scintillement autour du seuil : une fois qu'une collision est active, elle reste active jusqu'à ce que |ext_force| descende sous le produit collision_detection.force_threshold × collision_detection.exit_ratio. Réduire exit_ratio pour élargir la plage d'hystérésis (collisions plus persistantes) ; réglez la valeur à 1.0 pour désactiver l'hystérésis et n'utiliser qu'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 souvent modifiés​

ParamètreValeur par défautDescription
shape{rounded_box, r=0.01, b=(0.05,0.02,0.03)}Forme SDF définissant la zone morte
velocity_zone_width0.03 mÉpaisseur de la coque de contrôle en vitesse
max_velocity0.5 m/sVitesse maximale de navigation
velocity_ease"quadratic_in"Courbe de transition entre la distance et la vitesse
center.followfalseIndique si le centre suit le curseur
center.speed0.02 m/sVitesse de dérive lorsque follow = true

Liste complète des paramètres​

ChampTypeValeur par défautDescription
center.positionvec3(0, 0, 0)Centre initial — décalage par rapport au curseur lorsque relative = true, point absolu de l'espace de l'application lorsque false
center.relativebooltruetrue : position correspond à un décalage par rapport au curseur. false : point absolu de l'espace de l'application, converti en espace de montage à la frontière
center.followboolfalsefalse : le centre reste dans sa position initiale. true : le centre suit le curseur
center.speedfloat0.02Vitesse de dérive (m/s) lorsque follow = true ; 0.0 centrer le curseur à chaque cycle
shapeforme{rounded_box, r=0.01, b=(0.05,0.02,0.03)}Forme SDF de la zone morte
velocity_zone_widthfloat0.03Épaisseur de la coque de contrôle en vitesse (m)
max_velocityfloat0.5Vitesse maximale de navigation (m/s)
velocity_easechaîne de caractères"quadratic_in"Passage de la distance à la vitesse
reset_velocity_on_entrybooltrueRéinitialise la vitesse cumulée lorsque le curseur revient dans la zone de vitesse
bump_widthfloat0.005Bosse tactile en surface (m)
bump_stiffnessfloat200.0Constante de rigidité du ressort de la bosse à la surface
spring_innerfloat0.0Ressort au centre de la bulle
spring_surfacefloat10.0Remonte à la surface
spring_outerfloat15.0Ressort à la frontière extérieure
wall_stiffnessfloat700.0Rigidité du ressort de mur rigide au-delà de la limite extérieure
damping_innerfloat0.1Amortissement au centre
damping_surfacefloat4.0Amortissement par surface
damping_outerfloat7.0Amortissement à la frontière extérieure
rotation_enabledboolfalseApplique la rotation de l'espace de travail à la direction de navigation
scale_enabledboolfalseApplique l'échelle de l'espace de travail à la vitesse de navigation
collision_detection.enabledbooltrueBloque la circulation dans le sens de la collision
collision_detection.force_thresholdfloat1.0Intensité de la force externe nécessaire pour provoquer une collision (N)
collision_detection.inflate_ratiofloat2.0Multiplicateur de la largeur de la zone de vitesse lors d'une collision (doit être ≥ 1,0)
collision_detection.exit_ratiofloat0.7Taux d'hystérésis — reste en collision tant que |ext_force| < force_threshold × exit_ratio. Plage (0, 1] ; 1.0 désactive l'hystérésis
Champs masqués dans la version 3.5

Deux groupes de fonctionnalités ne figurent pas dans le schéma JSON 3.5, leurs implémentations étant en cours de refonte pour la version 3.6 :

  • Limites de l'avatar : les champs avatar_boundary_enabled, avatar_boundary et avatar_boundary_hysteresis.
  • Délimitation de l'espace de travail : les champs workspace_bounded, workspace_transition_speed et workspace_transition_ease.

Le code du tick se compile et s'exécute toujours avec les valeurs par défaut, mais les clients ne peuvent ni lire ni modifier ces champs via HTTP ou WebSocket. Dans la version 3.6, le contour de l'avatar réapparaîtra sous la forme d'un bounds de premier niveau, au même niveau que l'objet « bulle », avec une transformation de position complète ; la délimitation de l'espace de travail sera rétablie une fois l'analyse de la gigue du centre terminée.

Règles de validation​

  • velocity_zone_width > 0
  • 0 ≤ bump_width < velocity_zone_width
  • max_velocity > 0
  • bump_stiffness ≥ 0
  • spring_inner ≥ 0 et spring_inner ≤ spring_surface ≤ spring_outer
  • wall_stiffness ≥ 0
  • damping_inner ≥ 0 et damping_inner ≤ damping_surface ≤ damping_outer
  • collision_detection.force_threshold > 0
  • collision_detection.inflate_ratio ≥ 1.0
  • collision_detection.exit_ratio dans (0, 1]
  • center.speed ≥ 0

Un POST ou configure.navigation avec des paramètres non valides est rejeté et un événement invalid-value n'est pas émis ; la configuration précédente reste active.


Événements​

Nom de l'événementDéclenché lorsque
navigation-startedLa navigation est activée sur un appareil
navigation-updatedLa configuration de navigation est mise à jour alors qu'elle est déjà active
navigation-stoppedLa navigation est désactivée (désactivation explicite, DELETE ou la fin de votre session)
invalid-valueUne configuration de navigation est rejetée lors de la validation

Limites connues​

  • Délimitation de l'espace de travail et frontières de l'avatar masquées dans la version 3.5: ces deux groupes de fonctionnalités ne figurent pas dans le schéma JSON, car ils sont en cours de refonte pour la version 3.6. Voir la note ci-dessus, sous « Référence des paramètres ».
  • Mise à l'échelle non uniforme + rotation : lorsque rotation_enabled et scale_enabled Lorsqu'ils sont tous deux activés, la direction de la vitesse est légèrement imprécise, car la rotation n'est pas appliquée aux axes de mise à l'échelle.
  • Mise à l'échelle de la taille par appareil: les tailles des bulles (rayon, largeur de zone) ne sont pas mises à l'échelle en fonction du facteur d'échelle physique de l'appareil ; MInverse et Inverse3 utilisent les mêmes tailles absolues, qui peuvent donc sembler différentes sur chaque site.