Working on implementing server side physics on gam

This commit is contained in:
Vladislav Khorev committed 2026-01-16 00:01:44 +03:00
1 parent 1348efb5fe
commit e0453db063
8 files changed
+42 -69

No files matched your search

+19 -10
View File
@@ -568,7 +568,7 @@ namespace ZL
sparkEmitter.update(static_cast<float>(delta));
planetObject.update(static_cast<float>(delta));
updateRemotePlayers(static_cast<float>(delta));
extrapolateRemotePlayers(static_cast<float>(delta));
static float pingTimer = 0.0f;
pingTimer += delta;
@@ -1052,21 +1052,30 @@ namespace ZL
}
}
void Game::updateRemotePlayers(float deltaMs) {
void Game::extrapolateRemotePlayers(float deltaMs) {
auto now = std::chrono::steady_clock::now();
latestRemotePlayers = networkClient->getRemotePlayers();
for (auto& [id, rp] : latestRemotePlayers) {
// Увеличиваем фактор интерполяции (базируется на частоте Snapshot = 1000мс)
rp.interpolationFactor += deltaMs / 1000.0f;
if (rp.interpolationFactor > 1.0f) rp.interpolationFactor = 1.0f;
// 1. Рассчитываем, сколько времени прошло с момента получения последнего пакета (в секундах)
float age_s = std::chrono::duration<float>(now - rp.lastUpdateServerTime).count();
// Линейная интерполяция позиции
rp.state.position = rp.startPosition + (rp.targetPosition - rp.startPosition) * rp.interpolationFactor;
// Ограничим экстраполяцию (например, не более 2 секунд),
// чтобы в случае лага корабли не улетали в бесконечность
if (age_s > 2.0f) age_s = 2.0f;
// Сферическая интерполяция вращения (Slerp)
Eigen::Quaternionf currentQ = rp.startRotation.slerp(rp.interpolationFactor, rp.targetRotation);
rp.state.rotation = currentQ.toRotationMatrix();
// 2. Сбрасываем физическое состояние rp.state в значения из последнего пакета
// (Это важно: мы всегда экстраполируем от последнего достоверного серверного состояния)
// В WebSocketClient::updateRemotePlayer нужно убедиться, что rp.state обновляется данными из пакета.
// 3. Вызываем физику, чтобы "догнать" реальное время
// Мы передаем age_s как один большой шаг симуляции
rp.simulate_physics(age_s);
// Теперь rp.state.position и rp.state.rotation содержат актуальные
// предсказанные данные для рендеринга в текущем кадре.
}
}