Navigation
Das Modul „Navigation“ ermöglicht es einem „ Inverse3 “-Cursor, den Arbeitsbereich der Anwendung zu verschieben – was manchmal als „Rate-Control-Locomotion“ oder „gamepadartiges Driften“ bezeichnet wird. Anstatt dass der Cursor am Rand des physischen Arbeitsbereichs auf eine harte Wand trifft, gelangt er in eine weiche Hülle, in der sein Abstand zu einem virtuellen Mittelpunkt auf eine Geschwindigkeit abgebildet wird, mit der sich der gesamte Arbeitsbereich verschiebt. Je weiter der Cursor gedrückt wird, desto schneller scrollt die Szene.
Das primäre (und derzeit einzige) Verhalten ist die Bubble-Navigation. Die Form der Blase wird mithilfe eines SDF-Primitivs definiert – siehe „Was ist ein SDF?“ für eine Erläuterung des Konzepts.
Bubble-Navigation – Konzept
Eine virtuelle Blase ist um einen Mittelpunkt im Montageraum des Geräts verankert. Der Cursor durchläuft drei konzentrische Zonen:
┌──────────────────────────────────────────┐
│ WALL ZONE │ cursor beyond outer shell
│ ┌────────────────────────────────────┐ │
│ │ VELOCITY ZONE │ │ soft shell → scene moves
│ │ ┌──────────────────────────────┐ │ │
│ │ │ DEAD ZONE (inside) │ │ │ no scene movement
│ │ │ │ │ │
│ │ │ ● centre │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────┘ │ │
│ │ bubble surface │ │
│ └────────────────────────────────────┘ │
│ outer boundary │
└──────────────────────────────────────────┘
| Zone | Cursorposition | Verhalten |
|---|---|---|
| Totzone | Innerhalb der Blase | Keine Navigation. Leichte Dämpfung. Sie können die Szene frei bearbeiten. |
| Geschwindigkeitszone | Zwischen Oberfläche und äußerer Grenze | Die Funktion „Abstand → Geschwindigkeitskurve“ verschiebt den Arbeitsbereich in Richtung des Cursors. |
| Wandzone | Jenseits der Außengrenze | Eine harte Feder drückt den Cursor zurück in die Blase, und die Navigationsgeschwindigkeit wird begrenzt. |
In allen drei Zonen wirkt eine haptische Feder-Dämpfer-Kraft – Sie spüren die Oberfläche, die Driftschale und die Außenwand.
Schnellstart – Bubble-Navigation aktivieren
Die Navigation ist eine dauerhafte Einmal-Konfiguration – sobald Sie sie einmal gesendet haben, bleibt sie aktiv, bis Sie sie ausdrücklich beenden, den Dienst neu starten oder die Sitzung schließen.
Start (Minimal – Standard-Blase mit abgerundetem Quader)
- 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"}'
Beenden
- WebSocket
- HTTP
{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "disabled" }
}
}
]
}
curl -X DELETE "http://localhost:10001/inverse3/04C3/config/navigation?session=:0"
Weitere HTTP-Routen
| Methode | Pfad | Zweck |
|---|---|---|
GET | /{type}/{id}/config/navigation?session=<expr> | Aktuelle Navigationskonfiguration + Status |
POST | /{type}/{id}/config/navigation?session=<expr> | Navigation starten oder aktualisieren |
DELETE | /{type}/{id}/config/navigation?session=<expr> | Navigation beenden |
Katalog der Blasenformen
Die Totzone der Blase wird durch eine Form mit einer Vorzeichen-Abstandsfunktion (Signed Distance Function, SDF) beschrieben. Unterschiedliche Formen führen zu unterschiedlichen Navigationserlebnissen – ein abgerundeter Quader (der Standard) für eine komfortable rechteckige Ruhezone, eine Kugel für isotropes Driften, ein Ellipsoid, um bestimmte Achsen zu bevorzugen, und eine Kapsel für Korridore.
Abgerundeter Quader (Standard)
Die Standard-Totzone ist ein flacher Raum, der etwas höher als tief ist – so ausgelegt, dass er sich sowohl bei „ Inverse3 “ als auch bei „ MInverse “ angenehm anfühlt:
{
"shape": {
"primitive": "rounded_box",
"parameters": { "b": { "x": 0.05, "y": 0.02, "z": 0.03 }, "r": 0.01 }
}
}
Kugel – isotropes Driften
{
"shape": {
"primitive": "sphere",
"parameters": { "r": 0.05 }
}
}
Ellipsoid – in X/Z-Richtung breiter als in Y-Richtung
Verwenden Sie diese Form, wenn sich das horizontale Driften lockerer anfühlen soll als das vertikale:
{
"shape": {
"primitive": "ellipsoid",
"parameters": { "a": { "x": 0.06, "y": 0.03, "z": 0.06 } }
}
}
Kapsel – länglicher Korridor
Zwei Endpunkte a/b sowie ein Radius 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
}
}
}
Vollständiges Beispiel mit benutzerdefinierter Größe und Bewegungsgefühl:
{
"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"
}
}
}
}
]
}
Geschwindigkeitskurve
Der Abstand in der Geschwindigkeitszone wird vor der Umwandlung in eine Arbeitsbereichsgeschwindigkeit durch eine Easing-Kurve gesteuert. Wählen Sie das Easing aus, das der gewünschten Beschleunigung der Szene entspricht, wenn der Benutzer weiter in die Hülle drückt.
velocity_ease | Gefühl | Wann verwenden |
|---|---|---|
linear | Stetiger Anstieg | Vorhersehbar, guter Standard |
quadratic_in | Langsamer Start, dann schnellerer Vorschub | Präzise in Oberflächennähe, schnell bei großen Entfernungen |
cubic_in | Sehr langsamer Start | Sehr präzise, lange Wege mit ansteigender Rampe |
sine_out | Sanfter, schneller Start, flacht nahe der Außenkante ab | Reaktionsschnell, nur mäßig sanft |
quadratic_out | Schnell beim Einsteigen, komfortabel auf langen Strecken | Schnelles Antippen, komfortables Gleiten |
{ "velocity_ease": "quadratic_in", "max_velocity": 1.5 }
Verhalten des Mittelpunkts
Der Mittelpunkt der Blase wird über ein verschachteltes center-Objekt mit vier Feldern konfiguriert – position, relative, follow, speed –; es ersetzt das ältere, flache Layout aus center, center_enabled, center_mode und center_drift_speed.
{
"center": {
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"relative": true,
"follow": false,
"speed": 0.02
}
}
Wo der Mittelpunkt verankert wird
position und relative bestimmen die Ausgangsposition des Mittelpunkts bei der Aktivierung:
relative | Bedeutung von position |
|---|---|
true (Standard) | position ist ein Versatz zum Cursor – der anfängliche Mittelpunkt ist cursor + position. Beim Standardwert (0, 0, 0) erscheint die Sprechblase genau auf dem Cursor. |
false | position ist ein absoluter Punkt im Anwendungsbereich – Er wird beim Betreten des Montageraums umgerechnet und beim Verlassen wieder auf den Anwendungsraum zurückgerechnet, sodass die Werte bei der Hin- und Rückrechnung übereinstimmen. |
Wie sich der Mittelpunkt danach bewegt
follow und speed steuern das Verhalten pro Takt, sobald die Blase aktiv ist:
follow | speed | Verhalten | Bisheriges Äquivalent |
|---|---|---|---|
false (Standard) | ignoriert | Der Mittelpunkt bleibt an der Stelle, an der er initialisiert wurde – fester Mittelpunkt. | center_mode: "fixed" |
true | > 0 | Der Mittelpunkt driftet mit speed m/s in Richtung des Cursors, solange sich dieser darin befindet. | center_mode: "auto_follow" (mit center_drift_speed) |
true | 0.0 | Der Mittelpunkt springt bei jedem Takt auf den Cursor – das fühlt sich an wie Teleportation. | center_mode: "track_cursor" |
Das Standardverhalten des Mittelpunkts ist nun Fest (follow = false). Frühere Versionen ließen den Mittelpunkt standardmäßig in Richtung des Cursors driften (auto_follow). Setzen Sie center.follow = true, um das alte Driftverhalten wiederherzustellen, und passen Sie center.speed auf den alten Wert von center_drift_speed an.
Wenn follow = true Wenn der Cursor über die äußere Grenze hinausragt, folgt der Mittelpunkt dem Cursor unabhängig von speed, damit die Blase ihn weiterhin umschließt und der Cursor nicht entweichen kann.
Kollisionsverhalten
Die Blase reagiert auf äußere Cursorkräfte, die collision_detection.force_threshold überschreiten:
- Die Geschwindigkeitszone erweitert sich vorübergehend außer Betrieb (bis zum
collision_detection.inflate_ratio-Fächer ausvelocity_zone_width), damit Sie mehr Spielraum haben, um das Hindernis zu umfahren. - Wenn
collision_detection.enabledauftruesteht (der Standardwert), driftet der Mittelpunkt der Blase nicht in Richtung der Kollisionskraft, sodass Sie den Arbeitsbereich nicht an eine harte Wand ziehen können.
Die Kollisionserkennung nutzt Hysterese, um ein Flackern um den Schwellenwert herum zu vermeiden: Sobald eine Kollision aktiv ist, bleibt sie aktiv, bis |ext_force| unter das Produkt aus collision_detection.force_threshold × collision_detection.exit_ratio fällt. Senken Sie exit_ratio, um das Hysteresefenster zu erweitern (stärkere Kollisionen); setzen Sie den Wert auf 1.0, um die Hysterese zu deaktivieren und nur einen einzigen Schwellenwert zu verwenden.
{
"collision_detection": {
"enabled": true,
"force_threshold": 0.5,
"inflate_ratio": 2.0,
"exit_ratio": 0.7
}
}
Parameterreferenz
Am häufigsten angepasst
| Parameter | Standard | Beschreibung |
|---|---|---|
shape | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | SDF-Form, die die Totzone definiert |
velocity_zone_width | 0.03 m | Dicke der Steuerungshülle |
max_velocity | 0.5 m/s | Maximale Fahrgeschwindigkeit |
velocity_ease | "quadratic_in" | Abfallkurve von Abstand zu Geschwindigkeit |
center.follow | false | Ob der Mittelpunkt dem Cursor folgt |
center.speed | 0.02 m/s | Driftrate, wenn follow = true |
Vollständige Parameterliste
| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
center.position | vec3 | (0, 0, 0) | Anfänglicher Mittelpunkt — Cursor-Versatz bei relative = true, absoluter Highlight im App-Bereich bei false |
center.relative | bool | true | true: position ist ein Versatz zum Cursor. false: absoluter Punkt im App-Raum, der an der Grenze in den Mount-Raum umgerechnet wird |
center.follow | bool | false | false: Der Mittelpunkt bleibt an seiner initialisierten Position fixiert. true: Der Mittelpunkt folgt dem Cursor |
center.speed | float | 0.02 | Driftgeschwindigkeit (m/s) bei follow = true; 0.0 springt bei jedem Tick auf den Cursor |
shape | Form | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | SDF-Form der Totzone |
velocity_zone_width | float | 0.03 | Breite der Schale zur Geschwindigkeitsregelung (m) |
max_velocity | float | 0.5 | Maximale Fahrgeschwindigkeit (m/s) |
velocity_ease | String | "quadratic_in" | Überleitung von Abstand zu Geschwindigkeit |
reset_velocity_on_entry | bool | true | Die akkumulierte Geschwindigkeit auf null zurücksetzen, wenn der Cursor erneut in die Geschwindigkeitszone einfährt |
bump_width | float | 0.005 | Taktile Erhebung an der Oberfläche (m) |
bump_stiffness | float | 200.0 | Federkonstante der Oberflächenerhebung |
spring_inner | float | 0.0 | Feder am Mittelpunkt der Blase |
spring_surface | float | 10.0 | Feder an der Oberfläche |
spring_outer | float | 15.0 | Feder an der Außengrenze |
wall_stiffness | float | 700.0 | Feder der harten Wand jenseits der äußeren Grenze |
damping_inner | float | 0.1 | Dämpfung am Mittelpunkt |
damping_surface | float | 4.0 | Oberflächendämpfung |
damping_outer | float | 7.0 | Dämpfung an der äußeren Grenze |
rotation_enabled | bool | false | Drehung des Arbeitsbereichs auf die Navigationsrichtung anwenden |
scale_enabled | bool | false | Die Skalierung des Arbeitsraums auf die Navigationsgeschwindigkeit anwenden |
collision_detection.enabled | bool | true | Navigation in Kollisionsrichtung blockieren |
collision_detection.force_threshold | float | 1.0 | Größe der äußeren Kraft, ab der es zu einer Kollision kommt (N) |
collision_detection.inflate_ratio | float | 2.0 | Multiplikator für die Breite der Geschwindigkeitszone während einer Kollision (muss ≥ 1,0 sein) |
collision_detection.exit_ratio | float | 0.7 | Hysterese-Verhältnis — im Kollisionszustand verbleiben, bis |ext_force| < force_threshold × exit_ratio vergoldet. Bereich (0, 1]; 1.0 deaktiviert die Hysterese |
Zwei Funktionsgruppen sind im JSON-Schema der Version 3.5 nicht enthalten, während ihre Implementierungen für Version 3.6 überarbeitet werden:
- Klemmung an der Avatar-Grenze: die Felder
avatar_boundary_enabled,avatar_boundaryundavatar_boundary_hysteresis. - Begrenzung des Arbeitsraums: die Felder
workspace_bounded,workspace_transition_speedundworkspace_transition_ease.
Der Tick-Code wird weiterhin mit Standardwerten kompiliert und ausgeführt, aber Clients können diese Felder weder über HTTP noch über WebSocket lesen oder schreiben. In Version 3.6 kehrt die Avatar-Grenze als gleichrangiges, oberstes Element zurück bounds neben dem Blasenobjekt zurück, mit einer vollständigen Positionierungstransformation; die Begrenzung des Arbeitsraums wird wiederhergestellt, sobald die Untersuchung des Zitterns des Mittelpunkts abgeschlossen ist.
Validierungsregeln
velocity_zone_width > 00 ≤ bump_width < velocity_zone_widthmax_velocity > 0bump_stiffness ≥ 0spring_inner ≥ 0undspring_inner ≤ spring_surface ≤ spring_outerwall_stiffness ≥ 0damping_inner ≥ 0unddamping_inner ≤ damping_surface ≤ damping_outercollision_detection.force_threshold > 0collision_detection.inflate_ratio ≥ 1.0collision_detection.exit_ratioin(0, 1]center.speed ≥ 0
Ein POST oder configure.navigation Bei ungültigen Parametern wird die Anfrage abgelehnt, und es wird ein
invalid-value- Das Ereignis wird ausgelöst; die vorherige Konfiguration bleibt aktiv.
Ereignisse
| Ereignisname | Wird ausgelöst, wenn |
|---|---|
navigation-started | Die Navigation wird auf einem Gerät aktiviert |
navigation-updated | Die Navigationskonfiguration wird aktualisiert, während sie bereits aktiv ist |
navigation-stopped | Die Navigation wird beendet (explizite Deaktivierung, DELETE oder Sitzungsende) |
invalid-value | Eine Navigationskonfiguration wird bei der Validierung abgelehnt |
Bekannte Einschränkungen
- Begrenzung des Arbeitsraums und Avatar-Grenzen in 3.5 ausgeblendet: Beide Funktionsgruppen fehlen im JSON-Schema, während sie für 3.6 überarbeitet werden. Siehe den Hinweis oben unter „Parameterreferenz“.
- Ungleichmäßige Skalierung + Drehung: wenn
rotation_enabledundscale_enabledWenn beide aktiviert sind, ist die Geschwindigkeitsrichtung leicht ungenau – die Rotation wird nicht auf die Skalierungsachsen angewendet. - Größenskalierung pro Gerät: Blasengrößen (Radius, Zonenbreite) werden nicht mit dem physikalischen Skalierungsfaktor des Geräts skaliert – „ MInverse “ und „ Inverse3 “ verwenden dieselben absoluten Größen, die sich auf den einzelnen Geräten unterschiedlich anfühlen können.