1. 碰撞检测系统
物理世界
形状:
物理世界
形状:
- 相交、
- 接触(分离矢量,沿该矢量运动就能高效脱离碰撞妆容)、
- 凸(由形状内发射的光线不会穿越形状两次以上)
- 球体、
- 胶囊体、
- 轴对其包围盒AABB、
- 定向包围盒OBB、
- 离散定向多胞形discrete oriented polytope DOP、
- 任意凸体积、
- 多边形汤(碰撞引擎必须和每个三角形测试)、
- 复合形状
- 点和球体相交
- 球体和球体相交
- 分离轴定理:凸形状于该轴(分离轴)上的投影不重叠,能确定两个形状不相交。分离两个物体的轴/面称为分离线/面。三维空间中,分离轴仍然是个轴,分离线变成分离面。可以把形状逐一投影到各个潜在分离轴,并检查投影区间是否相交
- AABB相交:分离轴定理。三个轴x,y,z。只有在三个轴都重叠,才是相交的。
- 检测凸碰撞:GJK算法。依赖闵可夫斯基差:把A中的所有点与B中的所有点都成对相减,得到的集合就是闵可夫斯基差。当且仅当两个形状相交,闵可夫斯基差包含原点。GJK尝试在闵科夫斯基的凸包内,尝试找出一个包含原点的四面体。若找到,则相交。
- 运动物体间的碰撞:
-
- 离散的静态碰撞;
- sweep shape扫琼形状做静态测试(结果不准确);
- 连续碰撞检测continuous collision detection CCD,求出最早的冲击时间TOI
性能优化:
- 利用时间一致性避免每帧重新计算一些类型的信息
- 空间划分
- 粗略阶段,中间阶段,精确阶段:先AABB测试哪些物体会碰撞;再用符合形状的逼近包围体检测;最终进行青雀的碰撞检测
- 扫琼裁剪:sweep and prune,对各个膨胀提的AABB的最小,最大坐标再三个主轴上排序,然后通过遍历改有序表检测AABB之间是否重叠
碰撞查询:
- 光线投射:投射的物体并不存在于碰撞世界,不会影响其他物体。返回一个t值,P = P0 + td
- 形状投射:返回多个接触点。模拟玩家的脚
- Phantom:查询碰撞体是否在其他指定体积里。对于其他碰撞体是透明的,也不参与动力学模拟。
碰撞过滤:决定碰撞体之间的接触是否成立
- 碰撞掩码及碰撞层:掩码
- 碰撞回调:回调函数按自己的条件决定接受或拒绝碰撞
- 碰撞材质:包含碰撞属性,如音效,粒子效果,摩擦系数等等
2. 刚体动力学
6个自由度DOF
线性动力学(质点)
- 线性速度&加速度
- 力&动量
运动方程求解
- 力作为函数:位置、速度、时间等的函数(常微分方程(ordinary differential equation ODE))。类似弹簧
- 解析解:找到闭合式函数,描述所有可能的时间值t的刚体位置(例如抛物线),但是游戏中几乎不可能。
- 常微分方程的数值解的特性:
-
- 收敛性:delta_t趋近于0的时候,近似解趋近镇世界?
- 阶数:误差是O(t^?)
- 稳定性:数值解是否会稳定下来?
- 数值积分:游戏引擎使用数值积分求解运动方程
-
- 显示欧拉
pos(t2) = pos(t1) + v(t1)delta_t
v(t2)