Propagate ROT and VEL

This commit is contained in:
Vladislav Khorev 2026-01-17 11:05:04 +03:00
parent ff95163bcd
commit fbc420e894
3 changed files with 76 additions and 31 deletions

View File

@ -74,10 +74,12 @@ class Session : public std::enable_shared_from_this<Session> {
state_.discreteAngle = std::stoi(parts[2]); state_.discreteAngle = std::stoi(parts[2]);
state_.discreteMag = std::stof(parts[3]); state_.discreteMag = std::stof(parts[3]);
state_.apply_lag_compensation(now_server); state_.apply_lag_compensation(now_server);
retranslateMessage(msg);
} }
else if (parts[0] == "VEL") { else if (parts[0] == "VEL") {
state_.selectedVelocity = std::stoi(parts[2]); state_.selectedVelocity = std::stoi(parts[2]);
state_.apply_lag_compensation(now_server); state_.apply_lag_compensation(now_server);
retranslateMessage(msg);
} }
else if (parts[0] == "PING") { else if (parts[0] == "PING") {
state_.handle_full_sync(parts); state_.handle_full_sync(parts);
@ -85,7 +87,17 @@ class Session : public std::enable_shared_from_this<Session> {
} }
} }
void retranslateMessage(const std::string& msg)
{
std::string event_msg = "EVENT:" + std::to_string(id_) + ":" + msg;
std::lock_guard<std::mutex> lock(g_sessions_mutex);
for (auto& session : g_sessions) {
if (session->get_id() != id_) { // Íå øëåì îòïðàâèòåëþ
session->send_message(event_msg);
}
}
}
public: public:
@ -141,6 +153,10 @@ public:
ws_.async_write(net::buffer(*ss), [ss](beast::error_code, std::size_t) {}); ws_.async_write(net::buffer(*ss), [ss](beast::error_code, std::size_t) {});
} }
int get_id() const {
return id_;
}
private: private:
void do_read() { void do_read() {
ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) { ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) {

View File

@ -768,8 +768,21 @@ namespace ZL
} }
else { else {
// Если джойстик не зажат — сбрасываем дискретные значения и плавно замедляем вращение // Если джойстик не зажат — сбрасываем дискретные значения и плавно замедляем вращение
Environment::lastSentAngle = -1; int discreteAngle = -1;
Environment::lastSentMagnitude = 0.0f; float discreteMag = 0.0f;
if (discreteAngle != Environment::lastSentAngle || discreteMag != Environment::lastSentMagnitude) {
Environment::lastSentAngle = discreteAngle;
Environment::lastSentMagnitude = discreteMag;
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()
).count();
// Формируем сетевой пакет
// Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации
std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag);
networkClient->Send(msg);
}
float currentSpeed = Environment::currentAngularVelocity.norm(); float currentSpeed = Environment::currentAngularVelocity.norm();
@ -802,33 +815,6 @@ namespace ZL
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted; Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
} }
/*
if (Environment::tapDownHold) {
float diffx = Environment::tapDownCurrentPos(0) - Environment::tapDownStartPos(0);
float diffy = Environment::tapDownCurrentPos(1) - Environment::tapDownStartPos(1);
if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold
{
float rotationPower = sqrtf(diffx * diffx + diffy * diffy);
float deltaAlpha = rotationPower * delta * static_cast<float>(M_PI) / 500000.f;
Eigen::Vector3f rotationDirection(diffy, diffx, 0.0f);
rotationDirection.normalize(); // Eigen-way нормализация
// Создаем кватернион через AngleAxis
// Конструктор принимает (угол_в_радианах, ось_вращения)
Eigen::Quaternionf rotateQuat(Eigen::AngleAxisf(deltaAlpha, rotationDirection));
Matrix3f rotateMat = rotateQuat.toRotationMatrix();
Environment::shipMatrix = Environment::shipMatrix * rotateMat;
Environment::inverseShipMatrix = Environment::shipMatrix.inverse();
}
}*/
for (auto& p : projectiles) { for (auto& p : projectiles) {
if (p && p->isActive()) { if (p && p->isActive()) {
p->update(static_cast<float>(delta), renderer); p->update(static_cast<float>(delta), renderer);

View File

@ -68,13 +68,56 @@ namespace ZL {
void WebSocketClient::Poll() { void WebSocketClient::Poll() {
std::lock_guard<std::mutex> lock(queueMutex); std::lock_guard<std::mutex> lock(queueMutex);
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()
).count();
while (!messageQueue.empty()) { while (!messageQueue.empty()) {
std::string msg = messageQueue.front(); std::string msg = messageQueue.front();
messageQueue.pop(); messageQueue.pop();
if (msg.rfind("WORLD_UPDATE|", 0) == 0) { if (msg.rfind("EVENT:", 0) == 0) {
auto parts = split(msg, ':');
if (parts.size() < 5) continue; // EVENT:ID:TYPE:TIME:DATA...
int remoteId = std::stoi(parts[1]);
std::string subType = parts[2];
uint64_t sentTime = std::stoull(parts[3]);
std::lock_guard<std::mutex> pLock(playersMutex);
if (remotePlayers.count(remoteId)) {
auto& rp = remotePlayers[remoteId];
if (subType == "VEL") {
rp.selectedVelocity = std::stoi(parts[4]);
}
else if (subType == "ROT") {
rp.discreteAngle = std::stoi(parts[4]);
rp.discreteMag = std::stof(parts[5]);
}
// --- ÊÎÌÏÅÍÑÀÖÈß ËÀÃÀ ---
// Âû÷èñëÿåì çàäåðæêó â ñåêóíäàõ
float lag_s = static_cast<float>(now_ms - sentTime) / 1000.0f;
// Çàùèòà îò îòðèöàòåëüíîãî ëàãà (ðàçíèöà ÷àñîâ) èëè ñëèøêîì îãðîìíîãî
lag_s = std::max(0.0f, std::min(lag_s, 1.0f));
if (lag_s > 0.001f) {
// "Äîêðó÷èâàåì" ôèçèêó êîíêðåòíîãî èãðîêà íà âåëè÷èíó çàäåðæêè
// Â ClientState.h simulate_physics äîëæåí èñïîëüçîâàòü
// àêòóàëüíûå discreteAngle/Mag
rp.simulate_physics(lag_s);
}
// Îáíîâëÿåì ìåòêó âðåìåíè, ÷òîáû îáû÷íàÿ ýêñòðàïîëÿöèÿ â Game.cpp
// çíàëà, ÷òî ñîñòîÿíèå óæå àêòóàëüíî íà ìîìåíò now_ms
rp.lastUpdateServerTime = std::chrono::steady_clock::now();
}
}
else if (msg.rfind("WORLD_UPDATE|", 0) == 0) {
parseWorldUpdate(msg); parseWorldUpdate(msg);
std::cout << msg << std::endl;
} }
} }
} }