diff --git a/CMakeLists.txt b/CMakeLists.txt index 4765594..047b755 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,10 +17,9 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") # -rdy # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") # sanitizer -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment") project(LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description") diff --git a/Src/Client/ResourceCache.hpp b/Src/Client/ResourceCache.hpp index 466a72f..7d45f3b 100644 --- a/Src/Client/ResourceCache.hpp +++ b/Src/Client/ResourceCache.hpp @@ -127,8 +127,6 @@ public: class CacheHandlerBasic : public CacheHandler { Logger LOG = "CacheHandlerBasic"; - std::thread ReadThread, ReadWriteThread; - struct DataTask { CacheDatabase::HASH Hash; std::shared_ptr Data; @@ -144,6 +142,8 @@ class CacheHandlerBasic : public CacheHandler { SpinlockObject> ReadedQueue; bool NeedShutdown = false; + std::thread ReadThread, ReadWriteThread; + public: using Ptr = std::shared_ptr; diff --git a/Src/Client/ServerSession.cpp b/Src/Client/ServerSession.cpp index d445c15..34bb4eb 100644 --- a/Src/Client/ServerSession.cpp +++ b/Src/Client/ServerSession.cpp @@ -280,14 +280,14 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) { auto &pair = changeOrAddList_removeList[p.Id]; std::get<0>(pair).insert(p.Pos); } else if(l2 == ToClient::L2Content::ChunkNodes) { - // PP_Content_ChunkNodes &p = *dynamic_cast(pack); - // Pos::GlobalRegion rPos = p.Pos >> 2; - // Pos::bvec4u cPos = p.Pos & 0x3; + PP_Content_ChunkNodes &p = *dynamic_cast(pack); + Pos::GlobalRegion rPos = p.Pos >> 2; + Pos::bvec4u cPos = p.Pos & 0x3; - // Node *nodes = (Node*) Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z].Nodes; - // std::copy((const Node*) p.Nodes, ((const Node*) p.Nodes)+16*16*16, nodes); - // auto &pair = changeOrAddList_removeList[p.Id]; - // std::get<0>(pair).insert(p.Pos); + Node *nodes = (Node*) Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z].Nodes; + std::copy((const Node*) p.Nodes, ((const Node*) p.Nodes)+16*16*16, nodes); + auto &pair = changeOrAddList_removeList[p.Id]; + std::get<0>(pair).insert(p.Pos); } else if(l2 == ToClient::L2Content::RemoveRegion) { PP_Content_RegionRemove &p = *dynamic_cast(pack); diff --git a/Src/Client/Vulkan/VulkanRenderSession.cpp b/Src/Client/Vulkan/VulkanRenderSession.cpp index cc2528a..6a1421b 100644 --- a/Src/Client/Vulkan/VulkanRenderSession.cpp +++ b/Src/Client/Vulkan/VulkanRenderSession.cpp @@ -73,7 +73,8 @@ void VulkanRenderSession::init(Vulkan *instance) { if(!DescriptorPool) { std::vector pool_sizes = { {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3}, - {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 3} + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 3}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3} }; VkDescriptorPoolCreateInfo descriptor_pool = {}; @@ -616,8 +617,8 @@ void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered auto &table = External.ChunkVoxelMesh[worldId]; for(Pos::GlobalChunk pos : changeOrAddList) { - Pos::GlobalRegion rPos = pos >> 4; - Pos::bvec16u cPos = pos & 0xf; + Pos::GlobalRegion rPos = pos >> 2; + Pos::bvec4u cPos = pos & 0x3; auto &buffers = table[pos]; @@ -884,7 +885,7 @@ std::vector VulkanRenderSession::generateMeshForNodeChunks(con v.Tex = nodes[x][y][z].NodeId; - if((y+1) < 16 || nodes[x][y+1][z].NodeId != 0) { + if((y+1) >= 16 || nodes[x][y+1][z].NodeId == 0) { v.FX = 135+x*16; v.FY = 135+y*16+16; v.FZ = 135+z*16; @@ -892,28 +893,192 @@ std::vector VulkanRenderSession::generateMeshForNodeChunks(con v.TV = 0; out.push_back(v); - v.FX += 15; + v.FX += 16; v.TU = 65535; out.push_back(v); - v.FZ += 15; + v.FZ += 16; v.TV = 65535; out.push_back(v); v.FX = 135+x*16; - v.FY = 135+y*16+16; v.FZ = 135+z*16; v.TU = 0; v.TV = 0; out.push_back(v); - v.FX += 15; - v.FZ += 15; + v.FX += 16; + v.FZ += 16; v.TV = 65535; v.TU = 65535; out.push_back(v); - v.FX -= 15; + v.FX -= 16; + v.TU = 0; + out.push_back(v); + } + + if((y-1) < 0 || nodes[x][y-1][z].NodeId == 0) { + v.FX = 135+x*16; + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FZ += 16; + v.TV = 65535; + out.push_back(v); + + v.FX += 16; + v.TU = 65535; + out.push_back(v); + + v.FX = 135+x*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FX += 16; + v.FZ += 16; + v.TV = 65535; + v.TU = 65535; + out.push_back(v); + + v.FZ -= 16; + v.TV = 0; + out.push_back(v); + } + + if((x+1) >= 16 || nodes[x+1][y][z].NodeId == 0) { + v.FX = 135+x*16+16; + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FZ += 16; + v.TV = 65535; + out.push_back(v); + + v.FY += 16; + v.TU = 65535; + out.push_back(v); + + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FY += 16; + v.FZ += 16; + v.TV = 65535; + v.TU = 65535; + out.push_back(v); + + v.FZ -= 16; + v.TV = 0; + out.push_back(v); + } + + if((x-1) < 0 || nodes[x-1][y][z].NodeId == 0) { + v.FX = 135+x*16; + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FY += 16; + v.TU = 65535; + out.push_back(v); + + v.FZ += 16; + v.TV = 65535; + out.push_back(v); + + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FY += 16; + v.FZ += 16; + v.TV = 65535; + v.TU = 65535; + out.push_back(v); + + v.FY -= 16; + v.TU = 0; + out.push_back(v); + } + + if((z+1) >= 16 || nodes[x][y][z+1].NodeId == 0) { + v.FX = 135+x*16; + v.FY = 135+y*16; + v.FZ = 135+z*16+16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FY += 16; + v.TU = 65535; + out.push_back(v); + + v.FX += 16; + v.TV = 65535; + out.push_back(v); + + v.FX = 135+x*16; + v.FY = 135+y*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FX += 16; + v.FY += 16; + v.TV = 65535; + v.TU = 65535; + out.push_back(v); + + v.FY -= 16; + v.TU = 0; + out.push_back(v); + } + + if((z-1) < 0 || nodes[x][y][z-1].NodeId == 0) { + v.FX = 135+x*16; + v.FY = 135+y*16; + v.FZ = 135+z*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FX += 16; + v.TV = 65535; + out.push_back(v); + + v.FY += 16; + v.TU = 65535; + out.push_back(v); + + v.FX = 135+x*16; + v.FY = 135+y*16; + v.TU = 0; + v.TV = 0; + out.push_back(v); + + v.FX += 16; + v.FY += 16; + v.TV = 65535; + v.TU = 65535; + out.push_back(v); + + v.FX -= 16; v.TV = 0; out.push_back(v); } diff --git a/Src/Common/Abstract.cpp b/Src/Common/Abstract.cpp index 7d659a9..ae9a7ec 100644 --- a/Src/Common/Abstract.cpp +++ b/Src/Common/Abstract.cpp @@ -460,7 +460,7 @@ CompressedNodes compressNodes_byte(const Node* nodes) { assert(bytes_raw_profile >= 0 && bytes_raw_profile <= 3); // Количество байт на индекс uint8_t bytes_indices_profile = std::ceil(std::log2(profiles.size())/8); - assert(bytes_indices_profile >= 1 && bytes_indices_profile <= 2); + assert(bytes_indices_profile >= 0 && bytes_indices_profile <= 2); bool indices_profile = 3+bytes_raw_profile*profiles.size()+bytes_indices_profile*16*16*16 < bytes_raw_profile*16*16*16; @@ -486,6 +486,7 @@ CompressedNodes compressNodes_byte(const Node* nodes) { const Node &node = nodes[iter]; size_t index = std::binary_search(profiles.begin(), profiles.end(), node.NodeId); + compressed.push_back(index & 0xff); if(bytes_indices_profile > 1) compressed.push_back((index >> 8) & 0xff); diff --git a/Src/Common/Net.hpp b/Src/Common/Net.hpp index 40550f5..a5972c5 100644 --- a/Src/Common/Net.hpp +++ b/Src/Common/Net.hpp @@ -188,9 +188,9 @@ protected: tcp::socket Socket; static constexpr uint32_t - MAX_SIMPLE_PACKETS = 8192, + MAX_SIMPLE_PACKETS = 16384, MAX_SMART_PACKETS = MAX_SIMPLE_PACKETS/4, - MAX_PACKETS_SIZE_IN_WAIT = 1 << 24; + MAX_PACKETS_SIZE_IN_WAIT = 1 << 26; struct AsyncContext { volatile bool NeedShutdown = false, RunSendShutdowned = false; diff --git a/Src/Server/GameServer.cpp b/Src/Server/GameServer.cpp index 9662dde..ac53d69 100644 --- a/Src/Server/GameServer.cpp +++ b/Src/Server/GameServer.cpp @@ -111,7 +111,7 @@ void GameServer::BackingChunkPressure_t::run(int id) { for(int y = 0; y < 4; y++) for(int x = 0; x < 4; x++) { - auto &toPtr = dumpRegion.Nodes[Pos::bvec4u(x, y, z).pack()]; + auto &toPtr = dumpRegion.Nodes[Pos::bvec4u(x, y, z)]; const Node *fromPtr = (const Node*) ®ionObj.Nodes[0][0][0][x][y][z]; std::copy(fromPtr, fromPtr+16*16*16, toPtr.data()); } @@ -227,7 +227,7 @@ void GameServer::BackingChunkPressure_t::run(int id) { for(auto& [chunkPos, chunk] : region.Nodes) { CompressedNodes cmp = compressNodes(chunk.data()); Pos::GlobalChunk chunkPosR = (Pos::GlobalChunk(regionPos) << 2) + chunkPos; - + for(auto& ptr : region.NewCECs) { bool accepted = ptr->Remote->maybe_prepareChunkUpdate_Nodes(worldId, chunkPosR, cmp.Compressed, cmp.Defines); @@ -845,12 +845,24 @@ void GameServer::stepGeneratorAndLuaAsync(IWorldSaveBackend::TickSyncInfo_Out db for(int z = 0; z < 64; z++) for(int y = 0; y < 64; y++) for(int x = 0; x < 64; x++, ptr++) { - DefVoxelId_t id = *ptr > 0.5 ? 1 : 0; + // DefVoxelId_t id = *ptr > 0.9 ? 1 : 0; Pos::bvec64u nodePos(x, y, z); auto &node = obj.Nodes[Pos::bvec4u(nodePos >> 4).pack()][Pos::bvec16u(nodePos & 0xf).pack()]; - node.NodeId = id; + // node.NodeId = id; + // node.Meta = 0; + + if(y == (key.RegionPos.y % 64)) + node.NodeId = 1; + else + node.NodeId = 0; + node.Meta = 0; } + + // Node node; + // node.Data = 0; + // std::fill((Node*) obj.Nodes.data(), ((Node*) obj.Nodes.data())+64*64*64, node); + // obj.Nodes[0][0].NodeId = 1; } // Обработка идентификаторов на стороне луа diff --git a/Src/Server/GameServer.hpp b/Src/Server/GameServer.hpp index c76cf04..f74ec0f 100644 --- a/Src/Server/GameServer.hpp +++ b/Src/Server/GameServer.hpp @@ -211,8 +211,9 @@ class GameServer : public AsyncObject { auto lock = Input.lock(); for(auto& [worldId, region] : input) { - for(auto& regionPos : region) + for(auto& regionPos : region) { lock->push({worldId, regionPos}); + } } } diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index c46e0e2..89480d2 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -74,6 +74,9 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa if(lock) return false; + Pos::bvec4u localChunk = chunkPos & 0x3; + Pos::GlobalRegion regionPos = chunkPos >> 2; + /* Обновить зависимости Запросить недостающие @@ -98,7 +101,6 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa } auto iterWorld = ResUses.RefChunk.find(worldId); - Pos::bvec4u lChunk = (chunkPos & 0xf); if(iterWorld != ResUses.RefChunk.end()) // Исключим зависимости предыдущей версии чанка @@ -106,7 +108,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa auto iterRegion = iterWorld->second.find(chunkPos); if(iterRegion != iterWorld->second.end()) { // Уменьшим счётчик зависимостей - for(const DefVoxelId_t& id : iterRegion->second[lChunk.pack()].Voxel) { + for(const DefVoxelId_t& id : iterRegion->second[localChunk.pack()].Voxel) { auto iter = ResUses.DefVoxel.find(id); assert(iter != ResUses.DefVoxel.end()); // Воксель должен быть в зависимостях if(--iter->second == 0) { @@ -121,7 +123,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa iterWorld = ResUses.RefChunk.find(worldId); } - iterWorld->second[chunkPos][lChunk.pack()].Voxel = uniq_sorted_defines; + iterWorld->second[regionPos][localChunk.pack()].Voxel = uniq_sorted_defines; if(!newTypes.empty()) { // Добавляем новые типы в запрос @@ -154,6 +156,9 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global if(lock) return false; + Pos::bvec4u localChunk = chunkPos & 0x3; + Pos::GlobalRegion regionPos = chunkPos >> 2; + std::vector newTypes, /* Новые типы нод */ lostTypes /* Потерянные типы нод */; @@ -172,7 +177,6 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global } auto iterWorld = ResUses.RefChunk.find(worldId); - Pos::bvec4u lChunk = (chunkPos & 0xf); if(iterWorld != ResUses.RefChunk.end()) // Исключим зависимости предыдущей версии чанка @@ -180,7 +184,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global auto iterRegion = iterWorld->second.find(chunkPos); if(iterRegion != iterWorld->second.end()) { // Уменьшим счётчик зависимостей - for(const DefNodeId_t& id : iterRegion->second[lChunk.pack()].Node) { + for(const DefNodeId_t& id : iterRegion->second[localChunk.pack()].Node) { auto iter = ResUses.DefNode.find(id); assert(iter != ResUses.DefNode.end()); // Нода должна быть в зависимостях if(--iter->second == 0) { @@ -195,7 +199,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global iterWorld = ResUses.RefChunk.find(worldId); } - iterWorld->second[chunkPos][lChunk.pack()].Node = uniq_sorted_defines; + iterWorld->second[regionPos][localChunk.pack()].Node = uniq_sorted_defines; if(!newTypes.empty()) { // Добавляем новые типы в запрос