在Games104的第十节课《游戏引擎中物理系统的基础理论和算法 》中王希老师讲到了游戏引擎中的运动学算法,其中提到了显式欧拉积分会导致物体运动轨迹不符合预期,结果最近刚好在Godot的issue里面看到了一个完全相同原因导致的bug,真的十分甚至九分的生动形象了
Issue link: https://github.com/godotengine/godot/issues/102763
引擎代码:
if (!current_platform_velocity.is_zero_approx()) {
PhysicsServer3D::MotionParameters parameters(get_global_transform(), current_platform_velocity * delta, margin);
parameters.recovery_as_collision = true; // Also report collisions generated only from recovery.
parameters.exclude_bodies.insert(platform_rid);
if (platform_object_id.is_valid()) {
parameters.exclude_objects.insert(platform_object_id);
}
PhysicsServer3D::MotionResult floor_result;
if (move_and_collide(parameters, floor_result, false, false)) {
motion_results.push_back(floor_result);
CollisionState result_state;
_set_collision_direction(floor_result, result_state);
}
}
我们可以看到在创建`MotionParameters`的时候使用的future position 是 `current_platform_velocity * delta`,本质上就是显式欧拉积分,因为你用当前线速度乘以时间的话一定会导致圆周运动中的半径逐渐变大,这个地方是肯定不能直接这样简单相乘的
本人的PR: https://github.com/godotengine/godot/pull/110102
具体fix就不细说了,简单的刚体动力学,写这个帖子主要是觉得很有趣,看到这个bug就想到了games104,记录一下