Zum Hauptinhalt springen
Version: 3.5.x

Vorzeichenbehaftete Distanzfunktion (SDF)

Mit Signierten Distanzfeldern (SDFs) lassen sich einfache 3D-Geometrien (wie Kugeln, Quader, Kapseln und Ebenen) mithilfe einer Distanzfunktion anstelle von Netzmodellen beschreiben. In unserem Haptik-Stack wird ein SDF zu einem Kraftfeld, das Sie einer Gerätesitzung zuweisen können: Wenn sich der Cursor der Form nähert (oder in sie eintritt), erzeugt das System eine Normalkraft, deren Stärke von Entfernung, Reichweite und Beschleunigung abhängt.

Diese Seite dokumentiert die durch den Patch hinzugefügten bzw. aktualisierten öffentlichen API-Schnittstellen: die Nutzdaten des SDF-Haptik-Effekts, unterstützte Formen, Parameter sowie Beispiele für Anfragen und Antworten zum Erstellen, Aktualisieren, Auflisten und Löschen von SDF-Effekten.

Konzeptionelles Modell

Ein SDF-Effekt ist:

  • A Form (z. B. sphere, box, capsule, plane)
  • Eine Transformation (Position, Drehung und Skalierung des Effekts im Raum)
  • A Parameterobjekt (params) zur Konfiguration der ausgewählten Form (Radien, Endpunkte, Ausdehnung, Normalen usw.)
  • Steuerung der Kraft:
    • force_scale — Gesamtamplitudenmultiplikator
    • range — Dicke des „aktiven Bandes“ außerhalb der Oberfläche, wo die Kräfte gegen Null abfallen
    • ease + reverse_easing — wie die Kraft mit der Entfernung ansteigt
  • Einstellungen für die Komposition:
    • symmetry — wie das Verhältnis zwischen Innen und Außen behandelt wird
    • blend — wie sich mehrere SDF-Effekte miteinander verbinden

Sie können pro Gerät mehrere SDF-Effekte erstellen; jeder Effekt hat eine eindeutige id.

SDF-Effekt

{
"id": "string",
"transform": {
/* transform object */
},
"shape": "sphere | box | rounded_box | capsule | capsule_vertical | capped_cylinder | capped_cylinder_vertical | plane",
"params": {
/* shape parameters */
},
"force_scale": 1.0,
"range": 1.0,
"ease": "linear",
"reverse_easing": false,
"symmetry": "single | mirror | align",
"blend": "additive"
}

Feldreferenz

FeldTypErforderlichBedeutung
idStringEindeutige Kennung für diesen Effekt innerhalb eines Geräts.
transformObjektPosition des Effekts im Welt- bzw. Geräteraum.
shapeStringDie zu bewertende SDF-Primitive.
paramsObjektFormspezifische Parameter (siehe unten).
force_scaleZahlMultipliziert die endgültige Kraftgröße. Standard: 1.0.
rangeZahlEntfernung außerhalb der Fläche (in Metern), in der der Effekt aktiv ist. Standard: 1.0.
easeStringAngewandte Abflachungskurve [0..range]. Standard: linear.
reverse_easingBoolesche VariableFalls wahr, wird die Richtung der Beschleunigung umgekehrt. Standard: false.
symmetryStringWie „inside/outside“ behandelt wird (siehe unten). Standard: single.
blendStringWie sich mehrere SDF-Effekte miteinander verbinden. Standard: additive.

Formen und Parameter

Alle Formen werden über eine einzige params Objekt. Sie können nur die Felder, die Sie benötigen für die ausgewählte Form.

params Objekt

{
"r": 1.0,
"h": 0.0,
"a": [0.0, 0.0, 0.0],
"b": [0.0, 0.0, 0.0],
"n": [0.0, 1.0, 0.0]
}

Tipp: Die Werte werden im Effekt lokaler Raum (nach dem Auftragen transform).

Unterstützte Formen (aktuell)

Derzeit werden nur die folgenden SDF-Primitive unterstützt (mathematische Hintergründe finden Sie in der SDF-Galerie von IQ ):

Formshape WertVerwendete Parameter
Sphärespherer
Kastenboxb (Halbformate)
Abgerundete Schachtelrounded_boxb (Halbformate), r (Kurvenradius)
Kapsel (Segment)capsulea, b, r
Kapsel (vertikal)capsule_verticalh, r
Abgedeckter Zylinder (Segment)capped_cylindera, b, r
Zylinder mit Deckel (vertikal)capped_cylinder_verticalh, r
Flugzeugplanen, h

Hinweise zu den Konventionen

  • Vektoren sind Arrays: a, b, n sind 3D ([x,y,z]).
  • Kasten Verwendungszwecke b als Halbbereiche (z. B. b=[0.1,0.2,0.1]).
  • Flugzeug Verwendungszwecke n als das Normale und h als Versatz entlang der Normalen.
  • Vertikal Verwendung von Varianten h als halbe Höhe (Kapsel/Zylinder, zentriert am Ursprung entlang der lokalen Y-Achse).

Symmetrie

symmetry legt fest, wie sich das Feld in Bezug auf die Oberfläche verhält:

  • single — Standardverhalten. Die Unterscheidung zwischen „innen“ und „außen“ bleibt erhalten.
  • mirror — Nutzt den absoluten Abstand zur Oberfläche und wechselt die Richtung, wenn sich das Objekt „hinter“ der Oberfläche befindet, wodurch ein gespiegeltes Verhalten entsteht.
  • align — Verwendet den absoluten Abstand, ohne die Richtung umzukehren (nützlich für Effekte, bei denen „immer in dieselbe Richtung geschoben“ wird).

Abschwächung und Bandbreite

Die Kraftstärke nimmt mit zunehmender Entfernung von der Oberfläche zu:

  • An der Oberfläche (Abstand = 0): maximale Stärke (vorbehaltlich einer Abschwächung)
  • Aus der Ferne = range: Die Stärke wird zu 0 (inaktiv)

ease legt die Form der Abklingkurve fest. reverse_easing kehrt die Kurve um.


Befehle

  • "set_sdf": Lokalisierte SDF-Effekte erstellen/aktualisieren (Array von Elementen)
  • "remove_sdf": Effekte nach ID entfernen (Array von IDs)

SDF-Effekt festlegen / aktualisieren

{
"inverse3": [
{
"device_id": "049D",
"commands": {
"set_sdf": [
{
"id": "boundary_049D",
"transform": {
"position": {
"x": 0,
"y": -0.05,
"z": -0.04
},
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"scale": {
"x": 0.15,
"y": 0.1,
"z": 0.1
}
},
"shape": "sphere",
"force_scale": -2.0,
"range": 0.1,
"ease": "cubicInOut",
"reverse_easing": false,
"symmetry": "single",
"blend": "additive",
"params": {
"r": 1.0
}
}
]
}
}
]
}

Einen SDF-Effekt entfernen

{
"inverse3": [{
"device_id": "049D",
"commands": {
"remove_sdf": ["boundary_049D"]
}
}]
}
  • Jede ID im Array wird entfernt, sofern vorhanden.
  • Das Entfernen einer nicht vorhandenen ID wird als No-Op behandelt (der Aufruf ist sicher).

REST-API

Die SDF-Endpunkte folgen denselben Konventionen für das Routing nach Sitzung und Gerät wie der Rest der Haptik-API.

  • Ein Gerät kann über viele SDF-Effekte verfügen.
  • Jeder Effekt wird durch seine id.
  • Sie können Effekte einzeln oder gesammelt pro Gerät verwalten.

Routen

  • HOLEN

    • /{device_type}/{device_id}/sdf?session_id=<sid> → Gerätebereich (Liste der SDFs)
    • /{device_type}/{device_id}/sdf/{hfx_id}?session_id=<sid> → einzelne SDF
    • /{device_type}/*/sdf?session_id=<sid> → Sitzungsbereich (alle Geräte)
    • /{device_type}/*/sdf (nein session_id) → alle Sitzungen
  • BEITRAG

    • /{device_type}/{device_id}/sdf/{hfx_id}?session_id=<sid> Text: sdf_hfx (einen anlegen/aktualisieren)
    • /{device_type}/{device_id}/sdf?session_id=<sid> Text: device_sdf_dto (viele Einträge für das Gerät ersetzen oder bei Nichtvorhandensein einfügen)
  • LÖSCHEN

    • /{device_type}/{device_id}/sdf?session_id=<sid> oder .../sdf/{hfx_id}?session_id=<sid>
    • session_id=* unterstützt für „Alle löschen“.
Infos

Handler validieren device_type (inverse3 (nur), durchsetzen session_id/device_id Anwesenheit und Rückkehr 404 wegen fehlender Sitzung/Gerät/Effekt.

Wichtige Verhaltensmerkmale

  • GET-Routing umfasst: alle → Sitzung → Gerät → Einzelwirkung, abhängig von Pfad/Parametern.
  • POST erzwingt Pfad/Inhalt id Gewährleistet Konsistenz bei Schreibvorgängen mit einfacher Wirkung und setzt SDFs auf Geräteebene beim Posten einer Liste.
  • DELETE ist idempotent und gibt eine Standard-OK-Antwort zurück, auch wenn nichts gelöscht wurde

Beispiele

Eine Kugel, in die man hineindrücken kann

{
"id": "bubble",
"transform": {
/* place it where you want */
},
"shape": "sphere",
"params": {
"r": 0.12
},
"force_scale": 1.0,
"range": 0.08,
"ease": "linear",
"reverse_easing": false,
"symmetry": "single",
"blend": "additive"
}

Abgerundte Schachtel mit „weichen Wänden“

{
"id": "soft_wall",
"transform": {
/* oriented wall */
},
"shape": "rounded_box",
"params": {
"b": [
0.30,
0.02,
0.30
],
"r": 0.01
},
"force_scale": 0.9,
"range": 0.06,
"ease": "cubicInOut",
"reverse_easing": false,
"symmetry": "single",
"blend": "additive"
}

Segmentkapsel „Schiene“

{
"id": "rail",
"transform": {
/* position/rotate rail */
},
"shape": "capsule",
"params": {
"a": [
-0.15,
0.0,
0.0
],
"b": [
0.15,
0.0,
0.0
],
"r": 0.015
},
"force_scale": 0.7,
"range": 0.05,
"ease": "quadraticOut",
"reverse_easing": false,
"symmetry": "mirror",
"blend": "additive"
}

Ebene „unsichtbare Grenze“

{
"id": "boundary",
"transform": {
/* place plane */
},
"shape": "plane",
"params": {
"n": [
1.0,
0.0,
0.0
],
"h": 0.0
},
"force_scale": 0.8,
"range": 0.10,
"ease": "linear",
"reverse_easing": false,
"symmetry": "single",
"blend": "additive"
}