Новая система построения вершин чанков
This commit is contained in:
@@ -26,6 +26,12 @@ ServerSession::ServerSession(asio::io_context &ioc, std::unique_ptr<Net::AsyncSo
|
|||||||
{
|
{
|
||||||
assert(Socket.get());
|
assert(Socket.get());
|
||||||
|
|
||||||
|
Profiles.DefNode[0] = {0};
|
||||||
|
Profiles.DefNode[1] = {1};
|
||||||
|
Profiles.DefNode[2] = {2};
|
||||||
|
Profiles.DefNode[3] = {3};
|
||||||
|
Profiles.DefNode[4] = {4};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AM = AssetsManager::Create(ioc, "Cache");
|
AM = AssetsManager::Create(ioc, "Cache");
|
||||||
asio::co_spawn(ioc, run(AUC.use()), asio::detached);
|
asio::co_spawn(ioc, run(AUC.use()), asio::detached);
|
||||||
@@ -805,6 +811,38 @@ void ServerSession::update(GlobalTime gTime, float dTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Чанки
|
||||||
|
{
|
||||||
|
for(auto& [wId, lost] : regions_Lost_Result) {
|
||||||
|
auto iterWorld = Content.Worlds.find(wId);
|
||||||
|
if(iterWorld == Content.Worlds.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(const Pos::GlobalRegion& rPos : lost) {
|
||||||
|
auto iterRegion = iterWorld->second.Regions.find(rPos);
|
||||||
|
if(iterRegion != iterWorld->second.Regions.end())
|
||||||
|
iterWorld->second.Regions.erase(iterRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& [wId, voxels] : chunks_AddOrChange_Voxel_Result) {
|
||||||
|
auto& regions = Content.Worlds[wId].Regions;
|
||||||
|
|
||||||
|
for(auto& [pos, data] : voxels) {
|
||||||
|
regions[pos >> 2].Chunks[Pos::bvec4u(pos & 0x3).pack()].Voxels = std::move(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& [wId, nodes] : chunks_AddOrChange_Node_Result) {
|
||||||
|
auto& regions = Content.Worlds[wId].Regions;
|
||||||
|
|
||||||
|
for(auto& [pos, data] : nodes) {
|
||||||
|
regions[pos >> 2].Chunks[Pos::bvec4u(pos & 0x3).pack()].Nodes = std::move(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if(RS)
|
if(RS)
|
||||||
RS->tickSync(result);
|
RS->tickSync(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,9 +192,8 @@ void Vulkan::run()
|
|||||||
prevTime += dTime;
|
prevTime += dTime;
|
||||||
|
|
||||||
Screen.State = DrawState::Begin;
|
Screen.State = DrawState::Begin;
|
||||||
if(Game.RSession)
|
|
||||||
Game.RSession->pushStage(EnumRenderStage::ComposingCommandBuffer);
|
|
||||||
|
|
||||||
|
/// TODO: Нужно синхронизировать с vkQueue
|
||||||
{
|
{
|
||||||
std::lock_guard lock(Screen.BeforeDrawMtx);
|
std::lock_guard lock(Screen.BeforeDrawMtx);
|
||||||
while(!Screen.BeforeDraw.empty())
|
while(!Screen.BeforeDraw.empty())
|
||||||
@@ -204,12 +203,44 @@ void Vulkan::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Game.Выйти) {
|
||||||
|
Game.Выйти = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(Game.Session)
|
||||||
|
Game.Session->setRenderSession(nullptr);
|
||||||
|
|
||||||
|
if(Game.RSession)
|
||||||
|
Game.RSession = nullptr;
|
||||||
|
} catch(const std::exception &exc) {
|
||||||
|
LOG.error() << "Game.RSession->shutdown: " << exc.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(Game.Session)
|
||||||
|
Game.Session->shutdown(EnumDisconnect::ByInterface);
|
||||||
|
} catch(const std::exception &exc) {
|
||||||
|
LOG.error() << "Game.Session->shutdown: " << exc.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!NeedShutdown && glfwWindowShouldClose(Graphics.Window)) {
|
if(!NeedShutdown && glfwWindowShouldClose(Graphics.Window)) {
|
||||||
NeedShutdown = true;
|
NeedShutdown = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(Game.Session)
|
||||||
|
Game.Session->setRenderSession(nullptr);
|
||||||
|
|
||||||
|
if(Game.RSession)
|
||||||
|
Game.RSession = nullptr;
|
||||||
|
} catch(const std::exception &exc) {
|
||||||
|
LOG.error() << "Game.RSession->shutdown: " << exc.what();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(Game.Session)
|
if(Game.Session)
|
||||||
Game.Session->shutdown(EnumDisconnect::ByInterface);
|
Game.Session->shutdown(EnumDisconnect::ByInterface);
|
||||||
|
Game.Session = nullptr;
|
||||||
} catch(const std::exception &exc) {
|
} catch(const std::exception &exc) {
|
||||||
LOG.error() << "Game.Session->shutdown: " << exc.what();
|
LOG.error() << "Game.Session->shutdown: " << exc.what();
|
||||||
}
|
}
|
||||||
@@ -220,6 +251,8 @@ void Vulkan::run()
|
|||||||
} catch(const std::exception &exc) {
|
} catch(const std::exception &exc) {
|
||||||
LOG.error() << "Game.Server->GS.shutdown: " << exc.what();
|
LOG.error() << "Game.Server->GS.shutdown: " << exc.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Game.Session) {
|
if(Game.Session) {
|
||||||
@@ -2258,7 +2291,7 @@ void Vulkan::gui_MainMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan::gui_ConnectedToServer() {
|
void Vulkan::gui_ConnectedToServer() {
|
||||||
if(Game.Session) {
|
if(Game.Session && Game.RSession) {
|
||||||
if(ImGui::Begin("MainMenu", nullptr, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
|
if(ImGui::Begin("MainMenu", nullptr, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
|
||||||
{
|
{
|
||||||
ImGui::Text("fps: %2.2f World: %u Pos: %i %i %i Region: %i %i %i",
|
ImGui::Text("fps: %2.2f World: %u Pos: %i %i %i Region: %i %i %i",
|
||||||
@@ -2271,25 +2304,13 @@ void Vulkan::gui_ConnectedToServer() {
|
|||||||
LOG.debug();
|
LOG.debug();
|
||||||
|
|
||||||
if(ImGui::Button("Выйти")) {
|
if(ImGui::Button("Выйти")) {
|
||||||
try {
|
Game.Выйти = true;
|
||||||
if(Game.Session)
|
|
||||||
Game.Session->shutdown(EnumDisconnect::ByInterface);
|
|
||||||
} catch(const std::exception &exc) {
|
|
||||||
LOG.error() << "Game.Session->shutdown: " << exc.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
Game.RSession->pushStage(EnumRenderStage::Shutdown);
|
|
||||||
Game.RSession = nullptr;
|
|
||||||
Game.Session = nullptr;
|
|
||||||
Game.ImGuiInterfaces.pop_back();
|
Game.ImGuiInterfaces.pop_back();
|
||||||
int mode = glfwGetInputMode(Graphics.Window, GLFW_CURSOR);
|
|
||||||
if(mode != GLFW_CURSOR_NORMAL)
|
|
||||||
glfwSetInputMode(Graphics.Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
if(!Game.RSession)
|
if(Game.Выйти)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ public:
|
|||||||
std::thread MainThread;
|
std::thread MainThread;
|
||||||
std::shared_ptr<VulkanRenderSession> RSession;
|
std::shared_ptr<VulkanRenderSession> RSession;
|
||||||
ServerSession::Ptr Session;
|
ServerSession::Ptr Session;
|
||||||
|
bool Выйти = false;
|
||||||
|
|
||||||
std::list<void (Vulkan::*)()> ImGuiInterfaces;
|
std::list<void (Vulkan::*)()> ImGuiInterfaces;
|
||||||
std::unique_ptr<ServerObj> Server;
|
std::unique_ptr<ServerObj> Server;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
Sync.CV_CountInRun.notify_all();
|
Sync.CV_CountInRun.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug() << "Старт потока подготовки чанков к рендеру";
|
LOG.debug() << "Старт потока верширования чанков";
|
||||||
int timeWait = 1;
|
int timeWait = 1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -239,17 +239,8 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
for(int x = 0; x < 16; x++)
|
for(int x = 0; x < 16; x++)
|
||||||
fullNodes[x+0][y+1][0] = 1;
|
fullNodes[x+0][y+1][0] = 1;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
goto end;
|
||||||
{
|
|
||||||
result.NodeDefines.reserve(16*16*16);
|
|
||||||
for(int iter = 0; iter < 16*16*16; iter++)
|
|
||||||
result.NodeDefines.push_back((*chunk)[iter].NodeId);
|
|
||||||
std::sort(result.NodeDefines.begin(), result.NodeDefines.end());
|
|
||||||
auto eraseIter = std::unique(result.NodeDefines.begin(), result.NodeDefines.end());
|
|
||||||
result.NodeDefines.erase(eraseIter, result.NodeDefines.end());
|
|
||||||
result.NodeDefines.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
result.VoxelDefines.reserve(voxels->size());
|
result.VoxelDefines.reserve(voxels->size());
|
||||||
@@ -262,6 +253,16 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
result.VoxelDefines.shrink_to_fit();
|
result.VoxelDefines.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
result.NodeDefines.reserve(16*16*16);
|
||||||
|
for(int iter = 0; iter < 16*16*16; iter++)
|
||||||
|
result.NodeDefines.push_back((*chunk)[iter].NodeId);
|
||||||
|
std::sort(result.NodeDefines.begin(), result.NodeDefines.end());
|
||||||
|
auto eraseIter = std::unique(result.NodeDefines.begin(), result.NodeDefines.end());
|
||||||
|
result.NodeDefines.erase(eraseIter, result.NodeDefines.end());
|
||||||
|
result.NodeDefines.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
// Генерация вершин вокселей
|
// Генерация вершин вокселей
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -277,12 +278,12 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
for(int x = 0; x < 16; x++) {
|
for(int x = 0; x < 16; x++) {
|
||||||
int fullCovered = 0;
|
int fullCovered = 0;
|
||||||
|
|
||||||
fullCovered |= fullNodes[x+1][y][z];
|
fullCovered |= fullNodes[x+1+1][y+1][z+1];
|
||||||
fullCovered |= fullNodes[x-1][y][z] << 1;
|
fullCovered |= fullNodes[x+1-1][y+1][z+1] << 1;
|
||||||
fullCovered |= fullNodes[x][y+1][z] << 2;
|
fullCovered |= fullNodes[x+1][y+1+1][z+1] << 2;
|
||||||
fullCovered |= fullNodes[x][y-1][z] << 3;
|
fullCovered |= fullNodes[x+1][y+1-1][z+1] << 3;
|
||||||
fullCovered |= fullNodes[x][y][z+1] << 4;
|
fullCovered |= fullNodes[x+1][y+1][z+1+1] << 4;
|
||||||
fullCovered |= fullNodes[x][y][z-1] << 5;
|
fullCovered |= fullNodes[x+1][y+1][z+1-1] << 5;
|
||||||
|
|
||||||
if(fullCovered == 0b111111)
|
if(fullCovered == 0b111111)
|
||||||
continue;
|
continue;
|
||||||
@@ -394,7 +395,7 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
result.NodeVertexs.push_back(v);
|
result.NodeVertexs.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(fullCovered & 0b000001)) {
|
if(!(fullCovered & 0b000010)) {
|
||||||
v.FX = 135+x*16;
|
v.FX = 135+x*16;
|
||||||
v.FY = 135+y*16;
|
v.FY = 135+y*16;
|
||||||
v.FZ = 135+z*16+16;
|
v.FZ = 135+z*16+16;
|
||||||
@@ -515,13 +516,13 @@ void ChunkMeshGenerator::run(uint8_t id) {
|
|||||||
Sync.CV_CountInRun.notify_all();
|
Sync.CV_CountInRun.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug() << "Завершение потока подготовки чанков к рендеру";
|
LOG.debug() << "Завершение потока верширования чанков";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<
|
std::pair<
|
||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>,
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>,
|
||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>
|
||||||
> ModuleChunkPreparator::getChunksForRender(
|
> ChunkPreparator::getChunksForRender(
|
||||||
WorldId_t worldId, Pos::Object pos, uint8_t distance, glm::mat4 projView, Pos::GlobalRegion x64offset
|
WorldId_t worldId, Pos::Object pos, uint8_t distance, glm::mat4 projView, Pos::GlobalRegion x64offset
|
||||||
) {
|
) {
|
||||||
Pos::GlobalChunk playerChunk = pos >> Pos::Object_t::BS_Bit >> 4;
|
Pos::GlobalChunk playerChunk = pos >> Pos::Object_t::BS_Bit >> 4;
|
||||||
@@ -610,7 +611,7 @@ std::pair<
|
|||||||
VulkanRenderSession::VulkanRenderSession(Vulkan *vkInst, IServerSession *serverSession)
|
VulkanRenderSession::VulkanRenderSession(Vulkan *vkInst, IServerSession *serverSession)
|
||||||
: VkInst(vkInst),
|
: VkInst(vkInst),
|
||||||
ServerSession(serverSession),
|
ServerSession(serverSession),
|
||||||
MCP(vkInst, serverSession),
|
CP(vkInst, serverSession),
|
||||||
MainTest(vkInst), LightDummy(vkInst),
|
MainTest(vkInst), LightDummy(vkInst),
|
||||||
TestQuad(vkInst, sizeof(NodeVertexStatic)*6*3*2)
|
TestQuad(vkInst, sizeof(NodeVertexStatic)*6*3*2)
|
||||||
{
|
{
|
||||||
@@ -1231,11 +1232,11 @@ VulkanRenderSession::~VulkanRenderSession() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::prepareTickSync() {
|
void VulkanRenderSession::prepareTickSync() {
|
||||||
MCP.prepareTickSync();
|
CP.prepareTickSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::pushStageTickSync() {
|
void VulkanRenderSession::pushStageTickSync() {
|
||||||
MCP.pushStageTickSync();
|
CP.pushStageTickSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::tickSync(const TickSyncData& data) {
|
void VulkanRenderSession::tickSync(const TickSyncData& data) {
|
||||||
@@ -1243,8 +1244,10 @@ void VulkanRenderSession::tickSync(const TickSyncData& data) {
|
|||||||
// Профили
|
// Профили
|
||||||
// Чанки
|
// Чанки
|
||||||
|
|
||||||
ModuleChunkPreparator::TickSyncData mcpData;
|
ChunkPreparator::TickSyncData mcpData;
|
||||||
MCP.tickSync(mcpData);
|
mcpData.ChangedChunks = data.Chunks_ChangeOrAdd;
|
||||||
|
mcpData.LostRegions = data.Chunks_Lost;
|
||||||
|
CP.tickSync(mcpData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::setCameraPos(WorldId_t worldId, Pos::Object pos, glm::quat quat) {
|
void VulkanRenderSession::setCameraPos(WorldId_t worldId, Pos::Object pos, glm::quat quat) {
|
||||||
@@ -1416,7 +1419,7 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4;
|
Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4;
|
||||||
Pos::GlobalRegion x64offset_region = x64offset >> 2;
|
Pos::GlobalRegion x64offset_region = x64offset >> 2;
|
||||||
|
|
||||||
auto [voxelVertexs, nodeVertexs] = MCP.getChunksForRender(WorldId, Pos, 1, PCO.ProjView, x64offset_region);
|
auto [voxelVertexs, nodeVertexs] = CP.getChunksForRender(WorldId, Pos, 1, PCO.ProjView, x64offset_region);
|
||||||
|
|
||||||
{
|
{
|
||||||
static uint32_t l = TOS::Time::getSeconds();
|
static uint32_t l = TOS::Time::getSeconds();
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ private:
|
|||||||
/*
|
/*
|
||||||
Модуль обрабатывает рендер чанков
|
Модуль обрабатывает рендер чанков
|
||||||
*/
|
*/
|
||||||
class ModuleChunkPreparator {
|
class ChunkPreparator {
|
||||||
public:
|
public:
|
||||||
struct TickSyncData {
|
struct TickSyncData {
|
||||||
// Профили на которые повлияли изменения, по ним нужно пересчитать чанки
|
// Профили на которые повлияли изменения, по ним нужно пересчитать чанки
|
||||||
@@ -160,7 +160,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleChunkPreparator(Vulkan* vkInst, IServerSession* serverSession)
|
ChunkPreparator(Vulkan* vkInst, IServerSession* serverSession)
|
||||||
: VkInst(vkInst),
|
: VkInst(vkInst),
|
||||||
CMG(serverSession),
|
CMG(serverSession),
|
||||||
VertexPool_Voxels(vkInst),
|
VertexPool_Voxels(vkInst),
|
||||||
@@ -182,7 +182,7 @@ public:
|
|||||||
vkAssert(!vkCreateCommandPool(VkInst->Graphics.Device, &infoCmdPool, nullptr, &CMDPool));
|
vkAssert(!vkCreateCommandPool(VkInst->Graphics.Device, &infoCmdPool, nullptr, &CMDPool));
|
||||||
}
|
}
|
||||||
|
|
||||||
~ModuleChunkPreparator() {
|
~ChunkPreparator() {
|
||||||
CMG.changeThreadsCount(0);
|
CMG.changeThreadsCount(0);
|
||||||
|
|
||||||
if(CMDPool)
|
if(CMDPool)
|
||||||
@@ -203,6 +203,95 @@ public:
|
|||||||
// Пересчёт соседних чанков
|
// Пересчёт соседних чанков
|
||||||
// Проверить необходимость пересчёта чанков при изменении профилей
|
// Проверить необходимость пересчёта чанков при изменении профилей
|
||||||
|
|
||||||
|
// Добавляем к изменёным чанкам пересчёт соседей
|
||||||
|
{
|
||||||
|
std::vector<std::tuple<WorldId_t, Pos::GlobalChunk, uint32_t>> toBuild;
|
||||||
|
for(auto& [wId, chunks] : data.ChangedChunks) {
|
||||||
|
std::vector<Pos::GlobalChunk> list;
|
||||||
|
for(const Pos::GlobalChunk& pos : chunks) {
|
||||||
|
list.push_back(pos);
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(1, 0, 0));
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(-1, 0, 0));
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(0, 1, 0));
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(0, -1, 0));
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(0, 0, 1));
|
||||||
|
list.push_back(pos+Pos::GlobalChunk(0, 0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(list.begin(), list.end());
|
||||||
|
auto eraseIter = std::unique(list.begin(), list.end());
|
||||||
|
list.erase(eraseIter, list.end());
|
||||||
|
|
||||||
|
|
||||||
|
for(Pos::GlobalChunk& pos : list) {
|
||||||
|
Pos::GlobalRegion rPos = pos >> 2;
|
||||||
|
auto iterRegion = Requests[wId].find(rPos);
|
||||||
|
if(iterRegion != Requests[wId].end())
|
||||||
|
toBuild.emplace_back(wId, pos, iterRegion->second);
|
||||||
|
else
|
||||||
|
toBuild.emplace_back(wId, pos, Requests[wId][rPos] = NextRequest++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMG.Input.lock()->push_range(toBuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Чистим запросы и чанки
|
||||||
|
{
|
||||||
|
uint8_t frameRetirement = (FrameRoulette+FRAME_COUNT_RESOURCE_LATENCY) % FRAME_COUNT_RESOURCE_LATENCY;
|
||||||
|
for(auto& [wId, regions] : data.LostRegions) {
|
||||||
|
if(auto iterWorld = Requests.find(wId); iterWorld != Requests.end()) {
|
||||||
|
for(const Pos::GlobalRegion& rPos : regions)
|
||||||
|
if(auto iterRegion = iterWorld->second.find(rPos); iterRegion != iterWorld->second.end())
|
||||||
|
iterWorld->second.erase(iterRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(auto iterWorld = ChunksMesh.find(wId); iterWorld != ChunksMesh.end()) {
|
||||||
|
for(const Pos::GlobalRegion& rPos : regions)
|
||||||
|
if(auto iterRegion = iterWorld->second.find(rPos); iterRegion != iterWorld->second.end()) {
|
||||||
|
for(int iter = 0; iter < 4*4*4; iter++) {
|
||||||
|
auto& chunk = iterRegion->second[iter];
|
||||||
|
if(chunk.VoxelPointer)
|
||||||
|
VPV_ToFree[frameRetirement].emplace_back(std::move(chunk.VoxelPointer));
|
||||||
|
if(chunk.NodePointer)
|
||||||
|
VPN_ToFree[frameRetirement].emplace_back(std::move(chunk.NodePointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
iterWorld->second.erase(iterRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получаем готовые чанки
|
||||||
|
{
|
||||||
|
std::vector<ChunkMeshGenerator::ChunkObj_t> chunks = std::move(*CMG.Output.lock());
|
||||||
|
for(auto& chunk : chunks) {
|
||||||
|
auto iterWorld = Requests.find(chunk.WId);
|
||||||
|
if(iterWorld == Requests.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto iterRegion = iterWorld->second.find(chunk.Pos >> 2);
|
||||||
|
if(iterRegion == iterWorld->second.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(iterRegion->second != chunk.RequestId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Чанк ожидаем
|
||||||
|
auto& rChunk = ChunksMesh[chunk.WId][chunk.Pos >> 2][Pos::bvec4u(chunk.Pos & 0x3).pack()];
|
||||||
|
rChunk.Voxels = std::move(chunk.VoxelDefines);
|
||||||
|
if(!chunk.VoxelVertexs.empty())
|
||||||
|
rChunk.VoxelPointer = VertexPool_Voxels.pushVertexs(std::move(chunk.VoxelVertexs));
|
||||||
|
rChunk.Nodes = std::move(chunk.NodeDefines);
|
||||||
|
if(!chunk.NodeVertexs.empty())
|
||||||
|
rChunk.NodePointer = VertexPool_Nodes.pushVertexs(std::move(chunk.NodeVertexs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexPool_Voxels.update(CMDPool);
|
||||||
|
VertexPool_Nodes.update(CMDPool);
|
||||||
|
|
||||||
CMG.endTickSync();
|
CMG.endTickSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +369,7 @@ class VulkanRenderSession : public IRenderSession {
|
|||||||
glm::vec3 X64Offset_f, X64Delta; // Смещение мира относительно игрока в матрице вида (0 -> 64)
|
glm::vec3 X64Offset_f, X64Delta; // Смещение мира относительно игрока в матрице вида (0 -> 64)
|
||||||
glm::quat Quat;
|
glm::quat Quat;
|
||||||
|
|
||||||
ModuleChunkPreparator MCP;
|
ChunkPreparator CP;
|
||||||
|
|
||||||
AtlasImage MainTest, LightDummy;
|
AtlasImage MainTest, LightDummy;
|
||||||
Buffer TestQuad;
|
Buffer TestQuad;
|
||||||
|
|||||||
Reference in New Issue
Block a user