diff --git a/crates/engine/src/physics.rs b/crates/engine/src/physics.rs index dccfb32..ff2b734 100644 --- a/crates/engine/src/physics.rs +++ b/crates/engine/src/physics.rs @@ -190,6 +190,13 @@ impl PhysicsWorld { // По умолчанию Rapier ставит Y-вертикаль и −9.81 — у нас Z-вертикаль // и другие единицы, поэтому гравитацию задаём явно. world.gravity = Vector::new(0.0, 0.0, DEFAULT_GRAVITY); + // Rapier 0.36 по умолчанию ограничивает скорость 400 единицами + // (`normalized_max_linear_velocity`). В Source скорости выше: бег 650, + // физган до 5000, падения — тысячи. С этим пределом тело с заданной + // скоростью 1200 реально ехало 400 (замер), из-за чего физган не мог + // догнать игрока. Поднимаем предел до 100k, сохраняя защиту от + // нефинитных величин. + world.integration_parameters.normalized_max_linear_velocity = 100_000.0; Self { world, handles: Vec::new(), @@ -1195,12 +1202,9 @@ mod tests { /// скорость 1200 по X. За секунду тело обязано проехать ~1200 юнитов. /// Если проезжает меньше — его тормозит контакт/трение, и никакая /// пружина физгана не поможет (нужно другое решение). - // ОТКРЫТЫЙ БАГ (физган): шаг физики гасит заданную скорость ровно втрое - // (1200 -> 400) даже без пола, контактов, трения (combine rule Min), - // гравитации (gravity_scale 0) и damping (0.000). Именно поэтому проп - // отстаёт от игрока при любой пружине. Тест-страдалец: раскомментировать - // assert после починки. - #[ignore = "открытый баг: шаг физики делит скорость на 3"] + // Причина отставания пропа (найдена этим тестом): в Rapier 0.36 + // `normalized_max_linear_velocity` по умолчанию 400, и заданная скорость + // 1200 превращалась в 400. Теперь предел поднят в `PhysicsWorld::new`. #[test] fn body_with_set_velocity_actually_moves() { let mut physics = PhysicsWorld::new(); @@ -1239,8 +1243,10 @@ mod tests { "проехало за секунду при 1200: {moved:.1}, скорость после шага: {:.1}", v.length() ); - eprintln!("тест-страж: ожидание >1000, факт {moved:.1}"); - // assert!(moved > 1000.0, ...); // включить после починки шага физики + assert!( + moved > 1000.0, + "тело проехало только {moved:.1} из 1200 — предел скорости Rapier не поднят" + ); } /// Проп должен падать и останавливаться на полу, а не проваливаться.