Skip to main content
Version : 3.5.x

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 │
└──────────────────────────────────────────┘
ZonePosition du curseurComportement
Zone morteÀ l'intérieur de la bullePas de navigation. Atténuation de la lumière. Vous pouvez manipuler librement la scène.
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 muraleAu-delà de la limite extérieureUn 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)

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

Arrêter

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

Autres routes HTTP

MéthodeCheminObjectif
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_easeRessentirQuand l'utiliser
linearRampe constantePrévisible, un bon choix par défaut
quadratic_inUn démarrage lent, puis une accélérationPrécis près de la surface, rapide sur de longues distances
cubic_inUn démarrage très lentTrès précis, course longue, accélération progressive
sine_outDémarrage rapide et en douceur, plateau vers l'extérieurRéactif, majuscules en douceur
quadratic_outRapide au démarrage, confortable sur les longues distancesAccé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 :

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 à l'endroit où se trouve 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 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 :

followspeedComportementÉ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> 0Le 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)
true0.0Le centre s'aligne sur le curseur à chaque pas — on a l'impression de se téléporter.center_mode: "track_cursor"
Modification des paramètres par défaut dans la version 3.5

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_ratio fois velocity_zone_width) afin de laisser à l'utilisateur davantage de marge de manœuvre pour contourner l'obstacle.
  • Quand collision_detection.enabled est true (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ètresPar défautDescription
shape{rounded_box, r=0.01, b=(0.05,0.02,0.03)}SDF définissant la zone morte
velocity_zone_width0.03 mÉpaisseur de la coque de régulation de débit
max_velocity0.5 m/sVitesse maximale de navigation
velocity_ease"quadratic_in"Courbe d'accélération de la vitesse en fonction de la distance
center.followfalseLe centre suit-il le curseur ?
center.speed0.02 m/sVitesse de dérive lorsque follow = true

Liste complète des paramètres

Champ d'applicationTypePar défautDescription
center.positionvec3(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.relativebooltruetrue: 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.followboolfalsefalse: le centre reste fixe dans sa position initiale. true: le curseur reste centré
center.speedfloat0.02Vitesse de dérive (m/s) lorsque follow = true; 0.0 s'aligne sur le curseur à chaque tick
shapeforme{rounded_box, r=0.01, b=(0.05,0.02,0.03)}Forme SDF de la zone morte
velocity_zone_widthfloat0.03Largeur de la coque de régulation de débit (m)
max_velocityfloat0.5Vitesse maximale de navigation (m/s)
velocity_easechaîne de caractères"quadratic_in"Accélération progressive de la vitesse en fonction de la distance
reset_velocity_on_entrybooltrueRemettre à zéro la vitesse cumulée lorsque le curseur repasse dans la zone de vitesse
bump_widthfloat0.005Relief tactile à la surface (m)
bump_stiffnessfloat200.0Constante de rappel de la surface
spring_innerfloat0.0Le printemps au centre de la bulle
spring_surfacefloat10.0Le printemps à la surface
spring_outerfloat15.0Le printemps aux confins
wall_stiffnessfloat700.0Ressort à paroi rigide dépassant la limite extérieure
damping_innerfloat0.1Amortissement au centre
damping_surfacefloat4.0Amortissement en surface
damping_outerfloat7.0Amortissement à la limite extérieure
rotation_enabledboolfalseAppliquer la rotation de l'espace de travail à la direction de navigation
scale_enabledboolfalseAppliquer l'échelle de l'espace de travail à la vitesse de navigation
collision_detection.enabledbooltrueBloquer la navigation dans la direction de la collision
collision_detection.force_thresholdfloat1.0Intensité de la force externe à saisir pour 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.7Rapport 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
Champs masqués dans la version 3.5

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_boundaryet avatar_boundary_hysteresis.
  • Délimitation de l'espace de travail: les champs workspace_bounded, workspace_transition_speedet workspace_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 > 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

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énementLicencié lorsque
navigation-startedLa navigation est activée sur l'appareil
navigation-updatedLa configuration de la 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 la session)
invalid-valueUne 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_enabled et scale_enabled lorsqu'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.