一次物理帧
VVE 把一帧明确拆成预测、探测、结算和同步。读任何 main/main_c 时,都可以把源码放进下面这条流水线。
_get
↓
运动学迭代(按旧速度预测新位置与姿态)
↓
生成碰撞点并探测介质
↓
重力 + 位移/冲量/力偶矩/摩擦/姿态规整
↓
_sync_motion(写到 Minecraft 实体)
↓
_store(保存新的物理状态)1. 运动学迭代
质点只做平动:
p(n+1) = p(n) + v(n)刚体还要推进四元数相位。VVE 保存本段旋转的 quat_start、正交四元数 quat_orth 和相位 quat_phi:
q(φ) = quat_start · cos(φ) + quat_orth · sin(φ)角速度改变时,vve:object/_set_angular 从当前姿态建立新的旋转段,避免姿态跳变。四元数再转成 ivec/jvec/kvec 三个局部轴,供碰撞点、局部力和显示使用。
运动学阶段不施加重力、不处理碰撞,也不写世界实体。
2. 为什么先运动再碰撞
探测使用预测后的新位置。若一个点进入实心方块,介质返回穿透修正和接触响应;模型随后把它推出并改变速度。这是离散物理近似,不是连续碰撞检测,因此速度太大时仍可能跨过薄表面。
3. 广义力学结算
重力
典型模型直接对竖直速度做:
scoreboard players operation vy int -= vve_gravity int位移响应
shift 修改位置,主要用于消除穿透。它不是力,不应自动视作速度变化。
冲量与力偶矩
冲量 J 产生线速度变化;偏离质心的作用点还产生转动:
Δv = J / m
τ = r × J
Δω ≈ τ / I当前 _c 碰撞点方案会把偏心冲量拆成平动冲量和 couple,再分别应用。对新刚体主程序,优先参考 main_c 和 _iter_cpoints_c。
摩擦与姿态规整
摩擦通常以保留比例衰减切向速度。_regular 则根据支撑法向规整姿态、消除法向角速度;它用于稳定着陆,但不是碰到任何表面都应无条件调用的通用“防抖函数”。
4. 同步与写回不是一回事
_sync_motion 负责世界表现:根实体 Pos、display transformation、插值字段等。_store 负责下一帧计算所需的持久状态。只同步不 store,下一帧会从旧物理状态继续;只 store 不同步,内部数值正确但画面不动。
5. 完整帧、拆分帧与慢放入口
| 入口 | 典型用途 |
|---|---|
main | 传统完整物理帧 |
main_c | 偏心冲量拆为平动 + 力偶矩的完整帧,当前推荐 |
main_l | 带流体浮力路径 |
main_force | 介质探测与力学部分 |
main_sync | 显示/运动同步部分 |
main_slow_key | 慢放周期中的关键物理步 |
main_slow_mov | 慢放周期中的运动插值步 |
这些入口不是可以随意叠加的“效果开关”。同一游戏刻既跑 main_c 又跑 main_force,通常意味着重复受力;模拟器必须为每个对象选择一条完整且不重叠的调度路径。
6. 落地抖动的诊断顺序
- 确认对象每 tick 只执行一次主程序。
- 暂停并单步,打印
y/vy/angular_*。 - 检查接触点数量和
grab_layer_response是否在阈值附近来回变化。 - 检查位移修正是否在稳定判定后仍被重复施加。
- 检查
_regular与冲量/摩擦的顺序。 - 最后才检查 display interpolation;若物理分数稳定而画面抖,问题才属于显示层。