fix spaceship rotation fix sync boxes

This commit is contained in:
Vlad 2026-02-27 17:37:00 +06:00
parent be2aa76f8b
commit 7418bbbe27
5 changed files with 68 additions and 23 deletions

View File

@ -160,17 +160,19 @@ private:
std::lock_guard<std::mutex> lock(g_boxes_mutex);
std::string boxMsg = "BOXES:";
for (const auto& box : g_serverBoxes) {
for (size_t i = 0; i < g_serverBoxes.size(); ++i) {
const auto& box = g_serverBoxes[i];
Eigen::Quaternionf q(box.rotation);
boxMsg += std::to_string(box.position.x()) + ":" +
boxMsg += std::to_string(i) + ":" +
std::to_string(box.position.x()) + ":" +
std::to_string(box.position.y()) + ":" +
std::to_string(box.position.z()) + ":" +
std::to_string(q.w()) + ":" +
std::to_string(q.x()) + ":" +
std::to_string(q.y()) + ":" +
std::to_string(q.z()) + "|";
std::to_string(q.z()) + ":" +
(std::to_string(box.destroyed ? 1 : 0)) + "|";
}
if (!boxMsg.empty() && boxMsg.back() == '|') boxMsg.pop_back();
send_message(boxMsg);

View File

@ -331,7 +331,7 @@ namespace ZL
auto rotMatrix2 = quat2.toRotationMatrix();
cargoBase.RotateByMatrix(rotMatrix2);
//cargoBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY())).toRotationMatrix());
cargoBase.Move(Vector3f{ 1.2, 0, -5 });
cargoBase.Move(Vector3f{ 0, 0, -5 });
cargo.AssignFrom(cargoBase);
cargo.RefreshVBO();
@ -639,13 +639,15 @@ namespace ZL
// Если сервер прислал коробки, применяем их однократно вместо локальной генерации
if (!serverBoxesApplied && networkClient) {
auto sboxes = networkClient->getServerBoxes();
auto destroyedFlags = networkClient->getServerBoxDestroyedFlags();
if (!sboxes.empty()) {
boxCoordsArr.clear();
for (auto& b : sboxes) {
boxCoordsArr.resize(sboxes.size());
for (size_t i = 0; i < sboxes.size(); ++i) {
BoxCoords bc;
bc.pos = b.first;
bc.m = b.second;
boxCoordsArr.push_back(bc);
bc.pos = sboxes[i].first;
bc.m = sboxes[i].second;
boxCoordsArr[i] = bc;
}
boxRenderArr.resize(boxCoordsArr.size());
for (int i = 0; i < (int)boxCoordsArr.size(); ++i) {
@ -653,6 +655,11 @@ namespace ZL
boxRenderArr[i].RefreshVBO();
}
boxAlive.assign(boxCoordsArr.size(), true);
if (destroyedFlags.size() == boxAlive.size()) {
for (size_t i = 0; i < boxAlive.size(); ++i) {
if (destroyedFlags[i]) boxAlive[i] = false;
}
}
serverBoxesApplied = true;
}
}

View File

@ -41,6 +41,8 @@ namespace ZL {
virtual std::vector<std::pair<Eigen::Vector3f, Eigen::Matrix3f>> getServerBoxes() = 0;
virtual std::vector<bool> getServerBoxDestroyedFlags() { return {}; }
virtual std::vector<ProjectileInfo> getPendingProjectiles() = 0;
virtual std::vector<DeathInfo> getPendingDeaths() = 0;

View File

@ -41,36 +41,66 @@ namespace ZL {
return;
}
// Обработка списка коробок от сервера
if (msg.rfind("BOXES:", 0) == 0) {
std::string payload = msg.substr(6); // после "BOXES:"
std::vector<std::pair<Eigen::Vector3f, Eigen::Matrix3f>> parsedBoxes;
std::string payload = msg.substr(6);
std::vector<std::tuple<int, Eigen::Vector3f, Eigen::Matrix3f, bool>> parsed;
if (!payload.empty()) {
auto items = split(payload, '|');
for (auto& item : items) {
if (item.empty()) return;
if (item.empty()) continue;
auto parts = split(item, ':');
if (parts.size() < 7) return;
if (parts.size() < 9) {
return;
}
try {
float px = std::stof(parts[0]);
float py = std::stof(parts[1]);
float pz = std::stof(parts[2]);
int idx = std::stoi(parts[0]);
float px = std::stof(parts[1]);
float py = std::stof(parts[2]);
float pz = std::stof(parts[3]);
Eigen::Quaternionf q(
std::stof(parts[3]),
std::stof(parts[4]),
std::stof(parts[5]),
std::stof(parts[6])
std::stof(parts[6]),
std::stof(parts[7])
);
bool destroyed = (std::stoi(parts[8]) != 0);
Eigen::Matrix3f rot = q.toRotationMatrix();
parsedBoxes.emplace_back(Eigen::Vector3f{ px, py, pz }, rot);
parsed.emplace_back(idx, Eigen::Vector3f{ px, py, pz }, rot, destroyed);
}
catch (...) {
// пропускаем некорректную запись
return;
}
}
}
serverBoxes_ = std::move(parsedBoxes);
int maxIdx = -1;
for (auto& t : parsed) {
int idx = std::get<0>(t);
if (idx > maxIdx) maxIdx = idx;
}
if (maxIdx < 0) {
serverBoxes_.clear();
serverBoxesDestroyed_.clear();
return;
}
serverBoxes_.clear();
serverBoxes_.resize((size_t)maxIdx + 1);
serverBoxesDestroyed_.clear();
serverBoxesDestroyed_.resize((size_t)maxIdx + 1, true);
for (auto& t : parsed) {
int idx = std::get<0>(t);
const Eigen::Vector3f& pos = std::get<1>(t);
const Eigen::Matrix3f& rot = std::get<2>(t);
bool destroyed = std::get<3>(t);
if (idx >= 0 && idx < serverBoxes_.size()) {
serverBoxes_[idx] = { pos, rot };
serverBoxesDestroyed_[idx] = destroyed;
}
}
return;
}
if (msg.rfind("RESPAWN_ACK:", 0) == 0) {

View File

@ -13,8 +13,8 @@ namespace ZL {
protected:
std::unordered_map<int, ClientStateInterval> remotePlayers;
// Серверные коробки
std::vector<std::pair<Eigen::Vector3f, Eigen::Matrix3f>> serverBoxes_;
std::vector<bool> serverBoxesDestroyed_;
std::vector<ProjectileInfo> pendingProjectiles_;
std::vector<DeathInfo> pendingDeaths_;
@ -40,6 +40,10 @@ namespace ZL {
return serverBoxes_;
}
std::vector<bool> getServerBoxDestroyedFlags() {
return serverBoxesDestroyed_;
}
std::vector<ProjectileInfo> getPendingProjectiles() override;
std::vector<DeathInfo> getPendingDeaths() override;
std::vector<int> getPendingRespawns() override;