ナビゲーション
Navigation モジュールを使うと、Inverse3 カーソルでアプリケーションのワークスペースを移動できます。これは rate-control locomotion や「gamepad-like drift」とも呼ばれることがあります。 カーソルは物理ワークスペースの端で硬い壁にぶつかる代わりに、仮想の中心からの距離がワークスペース全体をスライドさせる速度に変換される ソフトなシェルの領域に入ります。カーソルを遠くへ押すほど、シーンは速くスクロールします。
主要な(現時点で唯一の)動作は Bubble Navigation です。バブルの形状は SDF プリミティブ を使って定義されます。概念については SDF とは? を参照してください。
Bubble Navigation — 概要
仮想の バブル は、デバイスのマウント空間内の中心点を基準に配置されます。 カーソルは、次の3つの同心円状のゾーンを通過します:
┌──────────────────────────────────────────┐
│ WALL ZONE │ cursor beyond outer shell
│ ┌────────────────────────────────────┐ │
│ │ VELOCITY ZONE │ │ soft shell → scene moves
│ │ ┌──────────────────────────────┐ │ │
│ │ │ DEAD ZONE (inside) │ │ │ no scene movement
│ │ │ │ │ │
│ │ │ ● centre │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────┘ │ │
│ │ bubble surface │ │
│ └────────────────────────────────────┘ │
│ outer boundary │
└──────────────────────────────────────────┘
| ゾーン | カーソル位置 | 動作 |
|---|---|---|
| デッドゾーン(不感帯) | バブルの内側 | ナビゲーションは行われません。軽いダンピングがかかります。シーンを自由に操作できます。 |
| 速度ゾーン | 表面と外側の境界の間 | 距離から速度への曲線により、カーソルの方向へワークスペースが移動します。 |
| 壁ゾーン | 外側の境界を超えた位置 | 硬いスプリングがカーソルを内側へ押し戻し、ナビゲーション速度は上限で飽和します。 |
3つのゾーンすべてにわたって ばね・ダンパー型の触覚力 が作用し、表面、ドリフトシェル、外側の壁を感じ取れます。
クイックスタート — Bubble Navigation を有効にする
ナビゲーションは永続的な一回限りの設定です。一度送信すると、明示的に停止するか、サービスを再起動するか、セッションを閉じるまで有効な状態が続きます。
開始(最小構成 — デフォルトの角丸ボックス型バブル)
- 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"}'
停止
- WebSocket
- HTTP
{
"inverse3": [
{
"device_id": "04C3",
"configure": {
"navigation": { "mode": "disabled" }
}
}
]
}
curl -X DELETE "http://localhost:10001/inverse3/04C3/config/navigation?session=:0"
その他の HTTP エンドポイント
| メソッド | パス | 用途 |
|---|---|---|
GET | /{type}/{id}/config/navigation?session=<expr> | 現在のナビゲーション設定と状態 |
POST | /{type}/{id}/config/navigation?session=<expr> | ナビゲーションの開始または更新 |
DELETE | /{type}/{id}/config/navigation?session=<expr> | ナビゲーションの停止 |
バブル形状一覧
バブルのデッドゾーン(不感帯)は、符号付き距離関数(SDF)の形状によって定義されます。 形状によってナビゲーションの感触は異なります。快適な矩形の静止ゾーンには角丸ボックス(デフォルト)、等方的なドリフトには球、特定の軸を優先する場合には楕円体、通路にはカプセルを使用します。
角丸ボックス(デフォルト)
デフォルトのデッドゾーンは、平らで、奥行きよりもわずかに高さのある体積です。Inverse3 と MInverse の両方で快適に感じられるよう調整されています:
{
"shape": {
"primitive": "rounded_box",
"parameters": { "b": { "x": 0.05, "y": 0.02, "z": 0.03 }, "r": 0.01 }
}
}
球 — 等方的なドリフト
{
"shape": {
"primitive": "sphere",
"parameters": { "r": 0.05 }
}
}
楕円体 — X/Z 方向が Y より広い
水平方向のドリフトを垂直方向よりも緩やかに感じさせたい場合に使用します:
{
"shape": {
"primitive": "ellipsoid",
"parameters": { "a": { "x": 0.06, "y": 0.03, "z": 0.06 } }
}
}
カプセル — 細長い通路
2つの端点 a/b と半径 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
}
}
}
サイズと動きの感触をカスタマイズした完全な例:
{
"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"
}
}
}
}
]
}
速度カーブ
速度ゾーンの距離は、ワークスペースの速度に変換される前にイージングカーブを通して写像されます。ユーザーがシェルの奥へ押し込んだときに、シーンがどのように加速してほしいかに合わせて、イージングを選択してください。
velocity_ease | 感触 | 使用する場面 |
|---|---|---|
linear | 一定の勾配 | 予測しやすく、標準的な選択肢として適しています |
quadratic_in | 立ち上がりは緩やか、その後の押し込みは速い | 表面付近では精密、長い移動は高速 |
cubic_in | 非常に緩やかな立ち上がり | 非常に精密、長い移動では徐々に加速 |
sine_out | 滑らかで速い立ち上がり、外側付近で頭打ち | 応答性が高く、穏やかに上限に達する |
quadratic_out | 進入時は速く、長距離でも快適 | 素早い微調整、快適な巡航 |
{ "velocity_ease": "quadratic_in", "max_velocity": 1.5 }
中心の動作
バブルの中心は、入れ子になった center オブジェクトで設定します。このオブジェクトは4つのフィールド — position、relative、follow、speed — を持ち、以前の center、center_enabled、center_mode、center_drift_speed からなるフラットなレイアウトに代わるものです。
{
"center": {
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"relative": true,
"follow": false,
"speed": 0.02
}
}
中心の基準位置
position と relative は、有効化時の中心の初期位置を制御します:
relative | position の意味 |
|---|---|
true(デフォルト) | position は カーソルからのオフセット です。初期の中心は cursor + position になります。デフォルトの (0, 0, 0) の場合、バブルはカーソルの位置にちょうど生成されます。 |
false | position は アプリケーション空間内の絶対点 です。入力時にマウント空間へ変換され、出力時にアプリケーション空間へ戻されるため、往復の値は一致します。 |
中心の以降の動き
バブルが有効になった後、ティックごとの動作は follow と speed によって制御されます:
follow | speed | 動作 | 従来の相当設定 |
|---|---|---|---|
false(デフォルト) | 無視 | 中心は初期化された位置に留まります — 固定された中心。 | center_mode: "fixed" |
true | > 0 | カーソルが内側にある間、中心は speed m/s でカーソルに向かってドリフトします。 | center_mode: "auto_follow"(center_drift_speed を使用) |
true | 0.0 | 中心は毎ティックカーソルにスナップします — テレポートのような感触。 | center_mode: "track_cursor" |
デフォルトの中心の動作は、現在 固定(follow = false)です。以前のバージョンでは、デフォルトでカーソルに向かってドリフトしていました(auto_follow)。古いドリフト動作に戻すには center.follow = true を設定し、center.speed を以前の center_drift_speed の値に合わせて調整してください。
follow = true の状態でカーソルが外側の境界を超えると、speed の値にかかわらず中心はカーソルを追従します。これにより、バブルがカーソルの周囲に留まり、カーソルが外へ逃げてしまうことを防ぎます。
衝突時の応答
バブルは、collision_detection.force_threshold を超える外部からのカーソル力に反応します:
- 速度ゾーンは一時的に 膨張 します(最大で
collision_detection.inflate_ratio倍のvelocity_zone_widthまで)。これにより、ユーザーは障害物を避けるための余裕を得られます。 collision_detection.enabledがtrue(デフォルト)の場合、バブルの中心は衝突力の方向へドリフトすることを拒否します。 これにより、ユーザーがワークスペースを硬い壁へ引きずり込むことを防ぎます。
衝突検出では、しきい値付近でのちらつきを避けるために ヒステリシス を使用します:
一度衝突が有効になると、|ext_force| が積 collision_detection.force_threshold × collision_detection.exit_ratio を下回るまで有効な状態が続きます。
exit_ratio を小さくするとヒステリシスの幅が広がり(衝突状態がより持続しやすくなります)、1.0 に設定するとヒステリシスを無効にして単一のしきい値を使用できます。
{
"collision_detection": {
"enabled": true,
"force_threshold": 0.5,
"inflate_ratio": 2.0,
"exit_ratio": 0.7
}
}
パラメーターリファレンス
よく調整されるパラメーター
| パラメーター | デフォルト | 説明 |
|---|---|---|
shape | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | デッドゾーンを定義するSDF形状 |
velocity_zone_width | 0.03 m | レートコントロールシェルの厚さ |
max_velocity | 0.5 m/s | ナビゲーションの最大速度 |
velocity_ease | "quadratic_in" | 距離から速度へのイージングカーブ |
center.follow | false | 中心がカーソルを追従するかどうか |
center.speed | 0.02 m/s | follow = true のときのドリフト速度 |
全パラメーター一覧
| フィールド | 型 | 既定値 | 説明 |
|---|---|---|---|
center.position | vec3 | (0, 0, 0) | 初期中心 — relative = true のときはカーソルからのオフセット、false のときはアプリ空間の絶対座標 |
center.relative | bool | true | true: position はカーソルからのオフセットです。false: アプリ空間の絶対座標で、境界でマウント空間に変換されます |
center.follow | bool | false | false: 中心は初期化された位置に固定されたままです。true: 中心がカーソルを追従します |
center.speed | float | 0.02 | follow = true のときの追従速度(m/s)。0.0 の場合は毎ティックカーソル位置にスナップします |
shape | shape | {rounded_box, r=0.01, b=(0.05,0.02,0.03)} | デッドゾーン SDF 形状 |
velocity_zone_width | float | 0.03 | 速度制御シェルの幅(m) |
max_velocity | float | 0.5 | ナビゲーションの最大速度(m/s) |
velocity_ease | string | "quadratic_in" | 距離から速度へのイージング |
reset_velocity_on_entry | bool | true | カーソルが速度ゾーンに再び入ったときに、累積速度をゼロにします |
bump_width | float | 0.005 | 表面の触覚バンプ(m) |
bump_stiffness | float | 200.0 | 表面バンプのばね定数 |
spring_inner | float | 0.0 | バブル中心のばね |
spring_surface | float | 10.0 | 表面のばね |
spring_outer | float | 15.0 | 外側境界のばね |
wall_stiffness | float | 700.0 | 外側境界を超えた先のハードウォール用ばね |
damping_inner | float | 0.1 | 中心のダンピング |
damping_surface | float | 4.0 | 表面のダンピング |
damping_outer | float | 7.0 | 外側境界のダンピング |
rotation_enabled | bool | false | ワークスペースの回転をナビゲーション方向に適用します |
scale_enabled | bool | false | ワークスペースのスケールをナビゲーション速度に適用します |
collision_detection.enabled | bool | true | 衝突方向へのナビゲーションをブロックします |
collision_detection.force_threshold | float | 1.0 | 衝突に入るための外力の大きさ(N) |
collision_detection.inflate_ratio | float | 2.0 | 衝突中の速度ゾーン幅に対する乗数(1.0 以上である必要があります) |
collision_detection.exit_ratio | float | 0.7 | ヒステリシス比。|ext_force| < force_threshold × exit_ratio となるまで衝突状態を維持します。範囲は (0, 1]。1.0 でヒステリシスを無効にします |
2 つの機能グループは、実装が 3.6 向けに再設計されている間、3.5 の JSON スキーマから除外されています:
- アバター境界のクランプ:
avatar_boundary_enabled、avatar_boundary、avatar_boundary_hysteresisの各フィールド。 - ワークスペースのバウンディング:
workspace_bounded、workspace_transition_speed、workspace_transition_easeの各フィールド。
tick 処理のコードは引き続きコンパイルされ、既定値を使って実行されますが、クライアントは HTTP または WebSocket を介してこれらのフィールドを読み書きできません。3.6 では、アバター境界は、完全な配置変換を持つバブルオブジェクトと同階層のトップレベル bounds として復活する予定です。ワークスペースのバウンディングは、中心ジッターの調査が完了した時点で復活する予定です。
検証ルール
velocity_zone_width > 00 ≤ bump_width < velocity_zone_widthmax_velocity > 0bump_stiffness ≥ 0spring_inner ≥ 0かつspring_inner ≤ spring_surface ≤ spring_outerwall_stiffness ≥ 0damping_inner ≥ 0かつdamping_inner ≤ damping_surface ≤ damping_outercollision_detection.force_threshold > 0collision_detection.inflate_ratio ≥ 1.0collision_detection.exit_ratioが(0, 1]の範囲内center.speed ≥ 0
無効なパラメータを指定した POST または configure.navigation は拒否され、invalid-value イベントが発行されます。以前の設定は引き続き有効なままです。
イベント
| イベント名 | 発火するタイミング |
|---|---|
navigation-started | デバイスでナビゲーションが有効化されたとき |
navigation-updated | ナビゲーションがすでに有効な状態で、設定が更新されたとき |
navigation-stopped | ナビゲーションが停止されたとき(明示的な無効化、DELETE、またはセッションの終了) |
invalid-value | ナビゲーション設定が検証によって拒否されたとき |
既知の制限事項
- 3.5 で非表示のワークスペースのバウンディングとアバター境界: 両機能グループは、3.6 向けに再設計されている間、JSON スキーマに含まれていません。上記のパラメータリファレンスの注記を参照してください。
- 非均一スケール + 回転:
rotation_enabledとscale_enabledの両方が有効な場合、速度方向がわずかに不正確になります。回転はスケール軸に適用されません。 - デバイスごとのサイズスケーリング: バブルのサイズ(半径、ゾーン幅)は、デバイスの物理的なスケール係数によってスケーリングされません。MInverse と Inverse3 は同じ絶対サイズを使用するため、デバイスごとに感触が異なる場合があります。