碰撞点、介质与响应
VVE 不把显示模型的三角形交给物理系统。物体提供少量碰撞点,介质根据点的位置、速度和等效质量生成响应。这一选择让纯命令物理可控且高效,也意味着模型作者必须主动选择采样密度。
碰撞点数据
| 临时字段 | 精度 | 含义 |
|---|---|---|
c_x/c_y/c_z | 10000 = 1格 | 世界坐标 |
c_vx/c_vy/c_vz | 10000 = 1格/帧 | 该点瞬时速度 |
c_mass | 1 = 1 | 此次响应使用的等效质量 |
刚体局部点 r_local=(u,v,w) 转换为:
text
r_world = R · r_local
p_c = center + r_world
v_c = velocity + angular_velocity × r_world因此旋转中的物体即使质心速度为零,边角仍可能高速撞击表面。
选择介质探测入口
| 函数 | 查询范围 | 何时使用 |
|---|---|---|
vve:_detect_material | 实体介质、特殊方块材质、水/岩浆、普通实心方块 | 默认通用选择 |
vve:_detect_liquid | 通用环境 + 浮力 | 已准备 buoyancy_area/h 的物体 |
vve:_detect_solid | 基础方块,不查实体介质 | 明确只撞世界地形 |
vve:_detect_slope | 内置白桦活板门斜面 + 普通实心 | 使用内置斜面约定 |
vve:_detect_large | 通用 + 大范围实体介质 | 曲面/大区域,接受更高查询成本 |
vve:_detect_box | 实体盒体 + 流体/空气,不撞普通实心方块 | 额外的物体间盒体探测 |
vve:_detect_render | 只调用 GELib 绘图 | 调试碰撞点,不产生物理响应 |
调用时需要当前执行位置、一个可移动的世界实体作为执行者,以及已经填好的 cpoint 临时对象。不要直接用玩家或物理实例充当内部运算实体。
介质返回什么
探测函数会覆盖共享响应区,主要信号包括:
| 响应 | 作用 |
|---|---|
material_response | 命中介质/材质类型 |
surface_response | 是否进行表面姿态处理 |
grab_layer_response | 支撑/附着层状态 |
bounce_layer_response | 反弹层状态 |
shift_* | 穿透位置修正 |
impulse_* + impulse_f* | 冲量作用点与向量 |
friction_response | 速度保留/摩擦参数 |
下一次探测会覆盖这些信号,所以多碰撞点模型必须“探测一个 → 立即接收/汇总 → 再探测下一个”。
方块介质与实体介质
方块介质来自世界方块与 #vve:* 标签,无需实例。实体介质则有中心、姿态、尺寸和 vve_material_type 等数据,通常把世界碰撞点变换到自身局部空间后判断是否进入几何体。
当 cublock/cubox 被另一个物体撞击时,响应还可把反向冲量写入被撞实例的 impulse_receiver,由其自己的物理帧结算。这样双方仍各自拥有状态,不让一个模型直接越权改写另一个模型的整套临时对象。
碰撞点越多并不总是越好
- 点少:成本低,但细长物体可能穿透、边缘接触粗糙;
- 点多:表面采样更细,但实体查询和响应汇总成倍增加;
- 点分布不当:即使数量多,也可能缺少真正需要的支撑位置;
- 显示模型变大后不重做点位:最常见的“看见碰到了但物理没有碰到”。
先用最少能表达形状的点,针对高速、狭窄接触或姿态稳定性增加采样,并用性能测试验证收益。
自定义介质的最小契约
自定义实体介质应做到:
- 明确候选实体的 tag 与搜索半径;
- 把
cpoint转到局部空间; - 返回一致方向的法向与非负侵入深度;
- 重置不适用的响应信号,避免前一次探测残留;
- 在修改共享临时区前后写清输入/输出;
- 对边界点、零速度、高速穿越和多个候选实体写测试。