Working on implementing server side physics on gam
This commit is contained in:
1 parent
1348efb5fe
commit
e0453db063
8 files changed
+42
-69
No files matched your search
+19
-10
@@ -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 содержат актуальные
|
||||
// предсказанные данные для рендеринга в текущем кадре.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user