带符号距离函数 (SDF)
带符号距离场(SDF)允许您使用距离函数来描述简单的3D几何形状(如球体、立方体、圆柱体和平面), 而非使用网格。在我们的触觉堆栈中,SDF会转化为一个力场,您可以将其附加到设备会话中:当光标接近(或 进入)该形状时,系统会产生一个法向力,其大小取决于距离、作用范围和缓动效果。
本页面记录了该补丁新增/更新的公共 API 接口:SDF 触觉效果有效载荷、支持的形状、参数, 以及用于创建、更新、列出和删除 SDF 效果的请求/响应示例。
概念模型
SDF 效果是:
- A 形状 (例如,
sphere,box,capsule,plane) - 变换(效果在空间中的位置、旋转和缩放)
- A 参数对象 (
params) 用于配置所选图形(半径、端点、范围、法线等) - 强制控制:
force_scale— 总星等倍数range— 表面外侧“活性带”的厚度,在此区域内力逐渐减小至零ease+reverse_easing— 力随距离如何增加
- 布局控件:
symmetry— 如何处理“内部/外部”的概念blend— 多种SDF效应如何相互作用
每个设备可以创建多个 SDF 效果;每个效果都有一个唯一的 id.
SDF效应
{
"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"
}
字段引用
| 现场 | 类型 | 必填 | 含义 |
|---|---|---|---|
id | 字符串 | ✅ | 该效果在设备内的唯一标识符。 |
transform | 反对 | ✅ | 在世界坐标系/设备坐标系中的姿态。 |
shape | 字符串 | ✅ | 待评估的 SDF 基元。 |
params | 反对 | ✅ | 特定形状的参数(见下文)。 |
force_scale | 数字 | ⛔ | 将最终力值乘以该系数。默认值: 1.0. |
range | 数字 | ⛔ | 效果生效的表面外距离(单位:米)。默认值: 1.0. |
ease | 字符串 | ⛔ | 应用平滑曲线 [0..range]. 默认: linear. |
reverse_easing | 布尔型 | ⛔ | 如果为真,则反转缓动方向。默认值: false. |
symmetry | 字符串 | ⛔ | “内部/外部”的处理方式(见下文)。默认值: single. |
blend | 字符串 | ⛔ | 多个SDF效果如何叠加。默认值: additive. |
形状与参数
所有形状均通过一个 params 对象。您可以提供 仅保留您需要的字段 针对所选形状。
params 反对
{
"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]
}
提示:这些值将在效果中进行解释 本地空间 (应用后
transform).
支持的形状(当前)
目前仅支持以下 SDF 基本图形(有关数学背景,请参阅IQ 的 SDF 图库):
| 形状 | shape 值 | 使用的参数 |
|---|---|---|
| 球体 | sphere | r |
| 框 | box | b (半幅) |
| 圆角框 | rounded_box | b (半幅), r (转弯半径) |
| 胶囊(片段) | capsule | a, b, r |
| 胶囊(竖版) | capsule_vertical | h, r |
| 带端盖的圆柱体(圆柱段) | capped_cylinder | a, b, r |
| 带盖圆筒(垂直) | capped_cylinder_vertical | h, r |
| 飞机 | plane | n, h |
关于约定俗成的说明
- 向量 是数组:
a,b,n是3D的([x,y,z]). - 框 用途
b作为半幅图(例如,b=[0.1,0.2,0.1]). - 飞机 用途
n作为常态和h沿法线方向偏移。 - 垂直 变体用法
h作为半高(沿局部 Y 轴以原点为中心的圆柱体/圆锥体)。
对称性
symmetry 控制该字段相对于表面的行为:
single— 标准行为。内部与外部的区分得以保留。mirror— 使用到表面的绝对距离,并在“位于”表面“后方”时反转方向,从而产生镜像效果。align— 使用绝对距离且不改变方向(适用于“始终朝同一方向推”的效果)。
渐变与范围
力的大小随距表面的距离增加而增大:
- 在表面(距离 =
0): 最大幅度(受缓冲机制限制) - 距离 =
range: 幅度变为0(已停用)
ease 定义了衰减曲线。 reverse_easing 使曲线反转。
命令
"set_sdf": 创建/更新本地化的 SDF 效果(项目数组)"remove_sdf": 按 ID 移除效果(ID 数组)
设置/更新 SDF 效果
{
"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
}
}
]
}
}
]
}
删除 SDF 效果
{
"inverse3": [{
"device_id": "049D",
"commands": {
"remove_sdf": ["boundary_049D"]
}
}]
}
- 如果数组中存在该 ID,则将其移除。
- 删除不存在的 ID 将被视为无操作(可安全调用)。
REST API
SDF 端点遵循与触觉 API 其余部分相同的会话/设备路由约定。
- 一个设备可以具有多种SDF效果。
- 每个效果都通过其
id.- 您可以按设备单独管理效果,也可以批量管理。
路线
-
获取
/{device_type}/{device_id}/sdf?session_id=<sid>→ 设备范围(SDF列表)/{device_type}/{device_id}/sdf/{hfx_id}?session_id=<sid>→ 单个 SDF/{device_type}/*/sdf?session_id=<sid>→ 会话范围(所有设备)/{device_type}/*/sdf(无session_id) → 所有会议
-
POST
/{device_type}/{device_id}/sdf/{hfx_id}?session_id=<sid>正文:sdf_hfx(创建/更新一个)/{device_type}/{device_id}/sdf?session_id=<sid>正文:device_sdf_dto(替换或更新/插入多个设备)
-
删除
/{device_type}/{device_id}/sdf?session_id=<sid>或.../sdf/{hfx_id}?session_id=<sid>session_id=*支持“清除全部”功能。
信息
处理程序进行验证 device_type (inverse3 (仅限),执行 session_id/device_id 存在,以及回归 404 因缺少会话/设备/效果。
行为亮点
- GET路由涵盖:所有 → 会话 → 设备 → 根据路径/参数产生单一效果。
- POST 请求强制要求路径/正文
id在执行单效写入时保持一致性,并在发布列表时合并/设置设备级 SDF。 - DELETE 操作具有幂等性,即使未删除任何内容,也会返回标准的成功响应
示例
可以按压的球形“气泡”
{
"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"
}
圆角盒“软壁”
{
"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"
}
分段胶囊“轨道”
{
"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"
}
平面的“无形边界”
{
"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"
}