*
This commit is contained in:
@@ -66,6 +66,8 @@ set(Boost_USE_STATIC_LIBS ON)
|
|||||||
|
|
||||||
set(BOOST_INCLUDE_LIBRARIES asio thread json)
|
set(BOOST_INCLUDE_LIBRARIES asio thread json)
|
||||||
set(BOOST_ENABLE_CMAKE ON)
|
set(BOOST_ENABLE_CMAKE ON)
|
||||||
|
set(BOOST_IOSTREAMS_ENABLE_ZLIB ON)
|
||||||
|
set(BOOST_INCLUDE_LIBRARIES asio thread json iostreams)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
Boost
|
Boost
|
||||||
URL https://github.com/boostorg/boost/releases/download/boost-1.87.0/boost-1.87.0-cmake.7z
|
URL https://github.com/boostorg/boost/releases/download/boost-1.87.0/boost-1.87.0-cmake.7z
|
||||||
@@ -73,7 +75,7 @@ FetchContent_Declare(
|
|||||||
DOWNLOAD_NO_EXTRACT FALSE
|
DOWNLOAD_NO_EXTRACT FALSE
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(Boost)
|
FetchContent_MakeAvailable(Boost)
|
||||||
target_link_libraries(luavox_common INTERFACE Boost::asio Boost::thread Boost::json)
|
target_link_libraries(luavox_common INTERFACE Boost::asio Boost::thread Boost::json Boost::iostreams)
|
||||||
|
|
||||||
# glm
|
# glm
|
||||||
# find_package(glm REQUIRED)
|
# find_package(glm REQUIRED)
|
||||||
@@ -116,7 +118,8 @@ target_link_libraries(luavox_common INTERFACE SQLite::SQLite3)
|
|||||||
|
|
||||||
# Static Assets
|
# Static Assets
|
||||||
file(GLOB_RECURSE ASSETS RELATIVE "${PROJECT_SOURCE_DIR}/assets" "assets/*.*")
|
file(GLOB_RECURSE ASSETS RELATIVE "${PROJECT_SOURCE_DIR}/assets" "assets/*.*")
|
||||||
add_custom_command(OUTPUT assets.o resources.cpp INPUT ${ASSETS}
|
file(GLOB_RECURSE ASSETS_A "${PROJECT_SOURCE_DIR}/assets" "assets/*.*")
|
||||||
|
add_custom_command(OUTPUT assets.o resources.cpp INPUT ${ASSETS_A}
|
||||||
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ${CMAKE_CURRENT_SOURCE_DIR}/Src/assets.py ${ASSETS}
|
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ${CMAKE_CURRENT_SOURCE_DIR}/Src/assets.py ${ASSETS}
|
||||||
COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/assets" && ld -r -b binary -o '${CMAKE_CURRENT_BINARY_DIR}/assets.o' ${ASSETS}
|
COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/assets" && ld -r -b binary -o '${CMAKE_CURRENT_BINARY_DIR}/assets.o' ${ASSETS}
|
||||||
COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/assets.o ${CMAKE_CURRENT_BINARY_DIR}/assets.o)
|
COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/assets.o ${CMAKE_CURRENT_BINARY_DIR}/assets.o)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ struct Chunk {
|
|||||||
// Кубы вокселей в чанке
|
// Кубы вокселей в чанке
|
||||||
std::vector<VoxelCube> Voxels;
|
std::vector<VoxelCube> Voxels;
|
||||||
// Ноды
|
// Ноды
|
||||||
Node Nodes[16][16][16];
|
std::array<Node, 16*16*16> Nodes;
|
||||||
// Ограничения прохождения света, идущего от солнца (от верха карты до верхней плоскости чанка)
|
// Ограничения прохождения света, идущего от солнца (от верха карты до верхней плоскости чанка)
|
||||||
// LightPrism Lights[16][16];
|
// LightPrism Lights[16][16];
|
||||||
};
|
};
|
||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Region {
|
struct Region {
|
||||||
Chunk Chunks[4][4][4];
|
std::array<Chunk, 4*4*4> Chunks;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct World {
|
struct World {
|
||||||
@@ -172,7 +172,7 @@ public:
|
|||||||
} CursorMode = EnumCursorMoveMode::Default;
|
} CursorMode = EnumCursorMoveMode::Default;
|
||||||
|
|
||||||
enum struct EnumCursorBtn {
|
enum struct EnumCursorBtn {
|
||||||
Left, Middle, Right, One, Two
|
Left, Right, Middle, One, Two
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct PP_Content_ChunkVoxels : public ParsedPacket {
|
|||||||
struct PP_Content_ChunkNodes : public ParsedPacket {
|
struct PP_Content_ChunkNodes : public ParsedPacket {
|
||||||
WorldId_t Id;
|
WorldId_t Id;
|
||||||
Pos::GlobalChunk Pos;
|
Pos::GlobalChunk Pos;
|
||||||
Node Nodes[16][16][16];
|
std::array<Node, 16*16*16> Nodes;
|
||||||
|
|
||||||
PP_Content_ChunkNodes(ToClient::L1 l1, uint8_t l2, WorldId_t id, Pos::GlobalChunk pos)
|
PP_Content_ChunkNodes(ToClient::L1 l1, uint8_t l2, WorldId_t id, Pos::GlobalChunk pos)
|
||||||
: ParsedPacket(l1, l2), Id(id), Pos(pos)
|
: ParsedPacket(l1, l2), Id(id), Pos(pos)
|
||||||
@@ -195,8 +195,8 @@ void ServerSession::onCursorMove(float xMove, float yMove) {
|
|||||||
|
|
||||||
static constexpr float PI = glm::pi<float>(), PI2 = PI*2, PI_HALF = PI/2, PI_DEG = PI/180;
|
static constexpr float PI = glm::pi<float>(), PI2 = PI*2, PI_HALF = PI/2, PI_DEG = PI/180;
|
||||||
|
|
||||||
deltaPYR.x = std::clamp(PYR.x + yMove*PI_DEG, -PI_HALF+PI_DEG, PI_HALF-PI_DEG)-PYR.x;
|
deltaPYR.x = std::clamp(PYR.x - yMove*PI_DEG, -PI_HALF+PI_DEG, PI_HALF-PI_DEG)-PYR.x;
|
||||||
deltaPYR.y = std::fmod(PYR.y + xMove*PI_DEG, PI2)-PYR.y;
|
deltaPYR.y = std::fmod(PYR.y - xMove*PI_DEG, PI2)-PYR.y;
|
||||||
deltaPYR.z = 0;
|
deltaPYR.z = 0;
|
||||||
|
|
||||||
double gTime = GTime;
|
double gTime = GTime;
|
||||||
@@ -208,7 +208,26 @@ void ServerSession::onCursorMove(float xMove, float yMove) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerSession::onCursorBtn(ISurfaceEventListener::EnumCursorBtn btn, bool state) {
|
void ServerSession::onCursorBtn(ISurfaceEventListener::EnumCursorBtn btn, bool state) {
|
||||||
|
if(!state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(btn == EnumCursorBtn::Left) {
|
||||||
|
Net::Packet packet;
|
||||||
|
|
||||||
|
packet << (uint8_t) ToServer::L1::System
|
||||||
|
<< (uint8_t) ToServer::L2System::BlockChange
|
||||||
|
<< uint8_t(0);
|
||||||
|
|
||||||
|
Socket->pushPacket(std::move(packet));
|
||||||
|
} else if(btn == EnumCursorBtn::Right) {
|
||||||
|
Net::Packet packet;
|
||||||
|
|
||||||
|
packet << (uint8_t) ToServer::L1::System
|
||||||
|
<< (uint8_t) ToServer::L2System::BlockChange
|
||||||
|
<< uint8_t(1);
|
||||||
|
|
||||||
|
Socket->pushPacket(std::move(packet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSession::onKeyboardBtn(int btn, int state) {
|
void ServerSession::onKeyboardBtn(int btn, int state) {
|
||||||
@@ -255,9 +274,9 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
if(Keys.CTRL)
|
if(Keys.CTRL)
|
||||||
mltpl *= 16;
|
mltpl *= 16;
|
||||||
|
|
||||||
Speed += glm::vec3(rot*glm::vec4(0, 0, 1, 1)*float(Keys.W))*mltpl;
|
Speed += glm::vec3(rot*glm::vec4(0, 0, -1, 1)*float(Keys.W))*mltpl;
|
||||||
Speed += glm::vec3(rot*glm::vec4(-1, 0, 0, 1)*float(Keys.A))*mltpl;
|
Speed += glm::vec3(rot*glm::vec4(-1, 0, 0, 1)*float(Keys.A))*mltpl;
|
||||||
Speed += glm::vec3(rot*glm::vec4(0, 0, -1, 1)*float(Keys.S))*mltpl;
|
Speed += glm::vec3(rot*glm::vec4(0, 0, 1, 1)*float(Keys.S))*mltpl;
|
||||||
Speed += glm::vec3(rot*glm::vec4(1, 0, 0, 1)*float(Keys.D))*mltpl;
|
Speed += glm::vec3(rot*glm::vec4(1, 0, 0, 1)*float(Keys.D))*mltpl;
|
||||||
Speed += glm::vec3(0, -1, 0)*float(Keys.SHIFT)*mltpl;
|
Speed += glm::vec3(0, -1, 0)*float(Keys.SHIFT)*mltpl;
|
||||||
Speed += glm::vec3(0, 1, 0)*float(Keys.SPACE)*mltpl;
|
Speed += glm::vec3(0, 1, 0)*float(Keys.SPACE)*mltpl;
|
||||||
@@ -275,7 +294,7 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
Pos::GlobalRegion rPos = p.Pos >> 2;
|
Pos::GlobalRegion rPos = p.Pos >> 2;
|
||||||
Pos::bvec4u cPos = p.Pos & 0x3;
|
Pos::bvec4u cPos = p.Pos & 0x3;
|
||||||
|
|
||||||
Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z].Voxels = std::move(p.Cubes);
|
Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.pack()].Voxels = std::move(p.Cubes);
|
||||||
|
|
||||||
auto &pair = changeOrAddList_removeList[p.Id];
|
auto &pair = changeOrAddList_removeList[p.Id];
|
||||||
std::get<0>(pair).insert(p.Pos);
|
std::get<0>(pair).insert(p.Pos);
|
||||||
@@ -284,8 +303,8 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
Pos::GlobalRegion rPos = p.Pos >> 2;
|
Pos::GlobalRegion rPos = p.Pos >> 2;
|
||||||
Pos::bvec4u cPos = p.Pos & 0x3;
|
Pos::bvec4u cPos = p.Pos & 0x3;
|
||||||
|
|
||||||
Node *nodes = (Node*) Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z].Nodes;
|
Node *nodes = (Node*) Data.Worlds[p.Id].Regions[rPos].Chunks[cPos.pack()].Nodes.data();
|
||||||
std::copy((const Node*) p.Nodes, ((const Node*) p.Nodes)+16*16*16, nodes);
|
std::copy(p.Nodes.begin(), p.Nodes.end(), nodes);
|
||||||
|
|
||||||
auto &pair = changeOrAddList_removeList[p.Id];
|
auto &pair = changeOrAddList_removeList[p.Id];
|
||||||
std::get<0>(pair).insert(p.Pos);
|
std::get<0>(pair).insert(p.Pos);
|
||||||
@@ -549,7 +568,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
(uint8_t) ToClient::L2Content::ChunkVoxels,
|
(uint8_t) ToClient::L2Content::ChunkVoxels,
|
||||||
wcId,
|
wcId,
|
||||||
pos,
|
pos,
|
||||||
unCompressVoxels(compressed)
|
unCompressVoxels(compressed) // TODO: вынести в отдельный поток
|
||||||
);
|
);
|
||||||
|
|
||||||
while(!NetInputPackets.push(packet));
|
while(!NetInputPackets.push(packet));
|
||||||
@@ -575,7 +594,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
pos
|
pos
|
||||||
);
|
);
|
||||||
|
|
||||||
unCompressNodes(compressed, (Node*) packet->Nodes);
|
unCompressNodes(compressed, (Node*) packet->Nodes.data()); // TODO: вынести в отдельный поток
|
||||||
|
|
||||||
while(!NetInputPackets.push(packet));
|
while(!NetInputPackets.push(packet));
|
||||||
|
|
||||||
@@ -586,7 +605,7 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
co_return;
|
co_return;
|
||||||
case ToClient::L2Content::RemoveRegion: {
|
case ToClient::L2Content::RemoveRegion: {
|
||||||
WorldId_t wcId = co_await sock.read<WorldId_t>();
|
WorldId_t wcId = co_await sock.read<WorldId_t>();
|
||||||
Pos::GlobalChunk pos;
|
Pos::GlobalRegion pos;
|
||||||
pos.unpack(co_await sock.read<Pos::GlobalRegion::Pack>());
|
pos.unpack(co_await sock.read<Pos::GlobalRegion::Pack>());
|
||||||
|
|
||||||
PP_Content_RegionRemove *packet = new PP_Content_RegionRemove(
|
PP_Content_RegionRemove *packet = new PP_Content_RegionRemove(
|
||||||
|
|||||||
@@ -2081,7 +2081,7 @@ void Vulkan::gui_MainMenu() {
|
|||||||
ImGui::InputText("Username", ConnectionProgress.Username, sizeof(ConnectionProgress.Username));
|
ImGui::InputText("Username", ConnectionProgress.Username, sizeof(ConnectionProgress.Username));
|
||||||
ImGui::InputText("Password", ConnectionProgress.Password, sizeof(ConnectionProgress.Password), ImGuiInputTextFlags_Password);
|
ImGui::InputText("Password", ConnectionProgress.Password, sizeof(ConnectionProgress.Password), ImGuiInputTextFlags_Password);
|
||||||
|
|
||||||
static bool flag = false;
|
static bool flag = true;
|
||||||
if(!flag) {
|
if(!flag) {
|
||||||
flag = true;
|
flag = true;
|
||||||
Game.Server = std::make_unique<ServerObj>(IOC);
|
Game.Server = std::make_unique<ServerObj>(IOC);
|
||||||
@@ -2686,12 +2686,16 @@ Buffer::Buffer(Buffer &&obj)
|
|||||||
obj.Instance = nullptr;
|
obj.Instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer& Buffer::operator=(Buffer &&obj)
|
Buffer& Buffer::operator=(Buffer &&obj) {
|
||||||
{
|
if(this == &obj)
|
||||||
|
return *this;
|
||||||
|
|
||||||
std::swap(Instance, obj.Instance);
|
std::swap(Instance, obj.Instance);
|
||||||
std::swap(Buff, obj.Buff);
|
std::swap(Buff, obj.Buff);
|
||||||
std::swap(Memory, obj.Memory);
|
std::swap(Memory, obj.Memory);
|
||||||
std::swap(Size, obj.Size);
|
std::swap(Size, obj.Size);
|
||||||
|
obj.Instance = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -251,6 +251,13 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
array[15] = {135, 135, 135-64, 0, 0, 0, 0, 0, 0};
|
array[15] = {135, 135, 135-64, 0, 0, 0, 0, 0, 0};
|
||||||
array[16] = {135+16, 135, 135-64-16, 0, 0, 0, 0, 65535, 65535};
|
array[16] = {135+16, 135, 135-64-16, 0, 0, 0, 0, 65535, 65535};
|
||||||
array[17] = {135, 135, 135-64-16, 0, 0, 0, 0, 0, 65535};
|
array[17] = {135, 135, 135-64-16, 0, 0, 0, 0, 0, 65535};
|
||||||
|
|
||||||
|
for(int iter = 0; iter < 18; iter++) {
|
||||||
|
array[18+iter] = array[iter];
|
||||||
|
array[18+iter].FZ -= 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VKCTX->TestQuad.unMapMemory();
|
VKCTX->TestQuad.unMapMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +438,7 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
.flags = 0,
|
.flags = 0,
|
||||||
.depthClampEnable = false,
|
.depthClampEnable = false,
|
||||||
.rasterizerDiscardEnable = false,
|
.rasterizerDiscardEnable = false,
|
||||||
.polygonMode = VK_POLYGON_MODE_LINE,
|
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||||
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||||
.depthBiasEnable = false,
|
.depthBiasEnable = false,
|
||||||
@@ -636,6 +643,7 @@ void VulkanRenderSession::onContentDefinesLost(std::unordered_map<EnumDefContent
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int changed = 0;
|
||||||
void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered_set<Pos::GlobalChunk>& changeOrAddList, const std::unordered_set<Pos::GlobalRegion>& remove) {
|
void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered_set<Pos::GlobalChunk>& changeOrAddList, const std::unordered_set<Pos::GlobalRegion>& remove) {
|
||||||
auto &table = External.ChunkVoxelMesh[worldId];
|
auto &table = External.ChunkVoxelMesh[worldId];
|
||||||
|
|
||||||
@@ -645,7 +653,7 @@ void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered
|
|||||||
|
|
||||||
auto &buffers = table[pos];
|
auto &buffers = table[pos];
|
||||||
|
|
||||||
const auto &chunk = ServerSession->Data.Worlds[worldId].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z];
|
const auto &chunk = ServerSession->Data.Worlds[worldId].Regions[rPos].Chunks[cPos.pack()];
|
||||||
|
|
||||||
if(chunk.Voxels.empty()) {
|
if(chunk.Voxels.empty()) {
|
||||||
VKCTX->VertexPool_Voxels.dropVertexs(std::get<0>(buffers));
|
VKCTX->VertexPool_Voxels.dropVertexs(std::get<0>(buffers));
|
||||||
@@ -655,11 +663,12 @@ void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered
|
|||||||
VKCTX->VertexPool_Voxels.relocate(voxels, std::move(vertexs));
|
VKCTX->VertexPool_Voxels.relocate(voxels, std::move(vertexs));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NodeVertexStatic> vertexs2 = generateMeshForNodeChunks(chunk.Nodes);
|
std::vector<NodeVertexStatic> vertexs2 = generateMeshForNodeChunks(chunk.Nodes.data());
|
||||||
|
|
||||||
if(vertexs2.empty()) {
|
if(vertexs2.empty()) {
|
||||||
VKCTX->VertexPool_Nodes.dropVertexs(std::get<1>(buffers));
|
VKCTX->VertexPool_Nodes.dropVertexs(std::get<1>(buffers));
|
||||||
} else {
|
} else {
|
||||||
|
changed++;
|
||||||
auto &nodes = std::get<1>(buffers);
|
auto &nodes = std::get<1>(buffers);
|
||||||
VKCTX->VertexPool_Nodes.relocate(nodes, std::move(vertexs2));
|
VKCTX->VertexPool_Nodes.relocate(nodes, std::move(vertexs2));
|
||||||
}
|
}
|
||||||
@@ -669,6 +678,8 @@ void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered
|
|||||||
if(iter != table.end())
|
if(iter != table.end())
|
||||||
table.erase(iter);
|
table.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOS::Logger("Vul").debug() << "Обработано " << changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Pos::GlobalRegion pos : remove) {
|
for(Pos::GlobalRegion pos : remove) {
|
||||||
@@ -704,6 +715,11 @@ void VulkanRenderSession::beforeDraw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd) {
|
void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd) {
|
||||||
|
{
|
||||||
|
X64Offset = Pos & ~((1 << Pos::Object_t::BS_Bit << 4 << 2)-1);
|
||||||
|
X64Offset_f = glm::vec3(X64Offset) / float(Pos::Object_t::BS);
|
||||||
|
X64Delta = glm::vec3(Pos-X64Offset) / float(Pos::Object_t::BS);
|
||||||
|
}
|
||||||
|
|
||||||
// Сместить в координаты игрока, повернуть относительно взгляда проецировать на экран
|
// Сместить в координаты игрока, повернуть относительно взгляда проецировать на экран
|
||||||
// Изначально взгляд в z-1
|
// Изначально взгляд в z-1
|
||||||
@@ -800,16 +816,27 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
static float Delta = 0;
|
static float Delta = 0;
|
||||||
Delta += dTime;
|
Delta += dTime;
|
||||||
|
|
||||||
glm::mat4 projView = glm::perspective<float>(glm::radians(75.f), float(VkInst->Screen.Width)/float(VkInst->Screen.Height), 0.5, std::pow(2, 17));
|
|
||||||
projView[1][1] *= -1;
|
|
||||||
glm::mat4 rotate = glm::mat4(1);
|
|
||||||
rotate = glm::translate(rotate, {0, 0, -4});
|
|
||||||
rotate = glm::rotate(rotate, 45.f/360*(2*glm::pi<float>()), {1, 0, 0});
|
|
||||||
rotate = glm::rotate(rotate, Delta/16*(2*glm::pi<float>()), {0, 1, 0});
|
|
||||||
rotate = glm::translate(rotate, {0, 0, 4});
|
|
||||||
|
|
||||||
PCO.ProjView = projView*rotate;
|
|
||||||
PCO.Model = glm::mat4(1);
|
PCO.Model = glm::mat4(1);
|
||||||
|
PCO.Model = glm::translate(PCO.Model, -X64Offset_f);
|
||||||
|
|
||||||
|
{
|
||||||
|
glm::mat4 proj = glm::perspective<float>(glm::radians(75.f), float(VkInst->Screen.Width)/float(VkInst->Screen.Height), 0.5, std::pow(2, 17));
|
||||||
|
proj[1][1] *= -1;
|
||||||
|
|
||||||
|
// Получили область рендера от левого верхнего угла
|
||||||
|
// x -1 -> 1; y 1 -> -1; z 0 -> -1
|
||||||
|
// Правило левой руки
|
||||||
|
// Перед полигонов определяется обходом против часовой стрелки
|
||||||
|
|
||||||
|
glm::mat4 view = glm::mat4(1);
|
||||||
|
// Смещаем мир относительно позиции игрока, чтобы игрок в пространстве рендера оказался в нулевых координатах
|
||||||
|
view = glm::translate(view, -X64Delta);
|
||||||
|
// Поворачиваем мир обратно взгляду игрока, чтобы его взгляд стал по направлению оси -z
|
||||||
|
view = glm::mat4(-Quat)*view;
|
||||||
|
|
||||||
|
// Сначала применяется матрица вида, потом проекции
|
||||||
|
PCO.ProjView = proj*view;
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdBindPipeline(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS, NodeStaticOpaquePipeline);
|
vkCmdBindPipeline(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS, NodeStaticOpaquePipeline);
|
||||||
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
@@ -818,11 +845,36 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
MainAtlas_LightMap_PipelineLayout, 0, 2,
|
MainAtlas_LightMap_PipelineLayout, 0, 2,
|
||||||
(const VkDescriptorSet[]) {MainAtlasDescriptor, VoxelLightMapDescriptor}, 0, nullptr);
|
(const VkDescriptorSet[]) {MainAtlasDescriptor, VoxelLightMapDescriptor}, 0, nullptr);
|
||||||
|
|
||||||
|
PCO.Model = glm::mat4(1);
|
||||||
VkBuffer vkBuffer = VKCTX->TestQuad;
|
VkBuffer vkBuffer = VKCTX->TestQuad;
|
||||||
VkDeviceSize vkOffset = 0;
|
VkDeviceSize vkOffsets = 0;
|
||||||
|
|
||||||
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffset);
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
vkCmdDraw(drawCmd, 6*3, 1, 0, 0);
|
vkCmdDraw(drawCmd, 6*3*2, 1, 0, 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4;
|
||||||
|
|
||||||
|
auto iterWorld = External.ChunkVoxelMesh.find(WorldId);
|
||||||
|
if(iterWorld != External.ChunkVoxelMesh.end()) {
|
||||||
|
glm::mat4 orig = PCO.Model;
|
||||||
|
|
||||||
|
for(auto &pair : iterWorld->second) {
|
||||||
|
if(auto& nodes = std::get<1>(pair.second)) {
|
||||||
|
glm::vec3 cpos(pair.first-x64offset);
|
||||||
|
PCO.Model = glm::translate(orig, cpos*16.f);
|
||||||
|
auto [vkBuffer, offset] = VKCTX->VertexPool_Nodes.map(nodes);
|
||||||
|
|
||||||
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(WorldPCO, Model), sizeof(WorldPCO::Model), &PCO.Model);
|
||||||
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
|
vkCmdDraw(drawCmd, nodes.VertexCount, 1, offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PCO.Model = orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes) {
|
std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes) {
|
||||||
@@ -912,7 +964,7 @@ std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(co
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(const Node nodes[16][16][16]) {
|
std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(const Node* nodes) {
|
||||||
std::vector<NodeVertexStatic> out;
|
std::vector<NodeVertexStatic> out;
|
||||||
NodeVertexStatic v;
|
NodeVertexStatic v;
|
||||||
|
|
||||||
@@ -920,15 +972,16 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
for(int y = 0; y < 16; y++)
|
for(int y = 0; y < 16; y++)
|
||||||
for(int x = 0; x < 16; x++)
|
for(int x = 0; x < 16; x++)
|
||||||
{
|
{
|
||||||
if(nodes[x][y][z].Data == 0)
|
size_t index = Pos::bvec16u(x, y, z).pack();
|
||||||
|
if(nodes[index].Data == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
v.Tex = nodes[x][y][z].NodeId;
|
v.Tex = nodes[index].NodeId;
|
||||||
|
|
||||||
if((y+1) >= 16 || nodes[x][y+1][z].NodeId == 0) {
|
if((y+1) >= 16 || nodes[Pos::bvec16u(x, y+1, z).pack()].NodeId == 0) {
|
||||||
v.FX = 135+x*16;
|
v.FX = 135+x*16;
|
||||||
v.FY = 135+y*16+16;
|
v.FY = 135+y*16+16;
|
||||||
v.FZ = 135+z*16;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
@@ -937,18 +990,18 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FZ += 16;
|
v.FZ -= 16;
|
||||||
v.TV = 65535;
|
v.TV = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX = 135+x*16;
|
v.FX = 135+x*16;
|
||||||
v.FZ = 135+z*16;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX += 16;
|
v.FX += 16;
|
||||||
v.FZ += 16;
|
v.FZ -= 16;
|
||||||
v.TV = 65535;
|
v.TV = 65535;
|
||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
@@ -958,106 +1011,73 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((y-1) < 0 || nodes[x][y-1][z].NodeId == 0) {
|
if((y-1) < 0 || nodes[Pos::bvec16u(x, y-1, z).pack()].NodeId == 0) {
|
||||||
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;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
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.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+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;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((x+1) >= 16 || nodes[x+1][y][z].NodeId == 0) {
|
if((x+1) >= 16 || nodes[Pos::bvec16u(x+1, y, z).pack()].NodeId == 0) {
|
||||||
v.FX = 135+x*16+16;
|
v.FX = 135+x*16+16;
|
||||||
v.FY = 135+y*16;
|
v.FY = 135+y*16;
|
||||||
v.FZ = 135+z*16;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
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.FZ -= 16;
|
||||||
v.TV = 0;
|
v.TV = 65535;
|
||||||
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);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FY += 16;
|
v.FY += 16;
|
||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FZ += 16;
|
|
||||||
v.TV = 65535;
|
|
||||||
out.push_back(v);
|
|
||||||
|
|
||||||
v.FY = 135+y*16;
|
v.FY = 135+y*16;
|
||||||
v.FZ = 135+z*16;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FY += 16;
|
v.FY += 16;
|
||||||
v.FZ += 16;
|
v.FZ -= 16;
|
||||||
v.TV = 65535;
|
v.TV = 65535;
|
||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FY -= 16;
|
v.FZ += 16;
|
||||||
v.TU = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((z+1) >= 16 || nodes[x][y][z+1].NodeId == 0) {
|
if((x-1) < 0 || nodes[Pos::bvec16u(x-1, y, z).pack()].NodeId == 0) {
|
||||||
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;
|
||||||
@@ -1069,18 +1089,18 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX += 16;
|
v.FZ -= 16;
|
||||||
v.TV = 65535;
|
v.TV = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX = 135+x*16;
|
|
||||||
v.FY = 135+y*16;
|
v.FY = 135+y*16;
|
||||||
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX += 16;
|
|
||||||
v.FY += 16;
|
v.FY += 16;
|
||||||
|
v.FZ -= 16;
|
||||||
v.TV = 65535;
|
v.TV = 65535;
|
||||||
v.TU = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
@@ -1090,20 +1110,20 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((z-1) < 0 || nodes[x][y][z-1].NodeId == 0) {
|
if((z+1) >= 16 || nodes[Pos::bvec16u(x, y, z+1).pack()].NodeId == 0) {
|
||||||
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;
|
v.FZ = 135+z*16+16;
|
||||||
v.TU = 0;
|
v.TU = 0;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX += 16;
|
v.FX += 16;
|
||||||
v.TV = 65535;
|
v.TU = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FY += 16;
|
v.FY += 16;
|
||||||
v.TU = 65535;
|
v.TV = 65535;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX = 135+x*16;
|
v.FX = 135+x*16;
|
||||||
@@ -1119,6 +1139,39 @@ std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(con
|
|||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
|
|
||||||
v.FX -= 16;
|
v.FX -= 16;
|
||||||
|
v.TU = 0;
|
||||||
|
out.push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((z-1) < 0 || nodes[Pos::bvec16u(x, y, z-1).pack()].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.TV = 65535;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FX += 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.FY -= 16;
|
||||||
v.TV = 0;
|
v.TV = 0;
|
||||||
out.push_back(v);
|
out.push_back(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,19 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
// Положение камеры
|
// Положение камеры
|
||||||
WorldId_t WorldId;
|
WorldId_t WorldId;
|
||||||
Pos::Object Pos;
|
Pos::Object Pos;
|
||||||
|
/*
|
||||||
|
Графический конвейер оперирует числами с плавающей запятой
|
||||||
|
Для сохранения точности матрица модели хранит смещения близкие к нулю (X64Delta)
|
||||||
|
глобальные смещения на уровне региона исключаются из смещения ещё при задании матрицы модели
|
||||||
|
|
||||||
|
X64Offset = позиция игрока на уровне регионов
|
||||||
|
X64Delta = позиция игрока в рамках региона
|
||||||
|
|
||||||
|
Внутри графического конвейера будут числа приблежённые к 0
|
||||||
|
*/
|
||||||
|
// Смещение дочерних объекто на стороне хоста перед рендером
|
||||||
|
Pos::Object X64Offset;
|
||||||
|
glm::vec3 X64Offset_f, X64Delta; // Смещение мира относительно игрока в матрице вида (0 -> 64)
|
||||||
glm::quat Quat;
|
glm::quat Quat;
|
||||||
|
|
||||||
struct VulkanContext {
|
struct VulkanContext {
|
||||||
@@ -61,7 +74,7 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
|
|
||||||
VulkanContext(Vulkan *vkInst)
|
VulkanContext(Vulkan *vkInst)
|
||||||
: MainTest(vkInst), LightDummy(vkInst),
|
: MainTest(vkInst), LightDummy(vkInst),
|
||||||
TestQuad(vkInst, sizeof(NodeVertexStatic)*6*3),
|
TestQuad(vkInst, sizeof(NodeVertexStatic)*6*3*2),
|
||||||
VertexPool_Voxels(vkInst),
|
VertexPool_Voxels(vkInst),
|
||||||
VertexPool_Nodes(vkInst)
|
VertexPool_Nodes(vkInst)
|
||||||
{}
|
{}
|
||||||
@@ -143,7 +156,7 @@ public:
|
|||||||
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd);
|
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd);
|
||||||
|
|
||||||
static std::vector<VoxelVertexPoint> generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes);
|
static std::vector<VoxelVertexPoint> generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes);
|
||||||
static std::vector<NodeVertexStatic> generateMeshForNodeChunks(const Node nodes[16][16][16]);
|
static std::vector<NodeVertexStatic> generateMeshForNodeChunks(const Node* nodes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateDescriptor_MainAtlas();
|
void updateDescriptor_MainAtlas();
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "Abstract.hpp"
|
#include "Abstract.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/iostreams/filtering_streambuf.hpp>
|
||||||
|
#include <boost/iostreams/copy.hpp>
|
||||||
|
#include <boost/iostreams/filter/zlib.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
namespace LV {
|
namespace LV {
|
||||||
@@ -99,7 +103,7 @@ CompressedVoxels compressVoxels_byte(const std::vector<VoxelCube>& voxels) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {compressed, defines};
|
return {compressLinear(compressed), defines};
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedVoxels compressVoxels_bit(const std::vector<VoxelCube>& voxels) {
|
CompressedVoxels compressVoxels_bit(const std::vector<VoxelCube>& voxels) {
|
||||||
@@ -245,7 +249,7 @@ CompressedVoxels compressVoxels_bit(const std::vector<VoxelCube>& voxels) {
|
|||||||
for(size_t iter = 0; iter < buff.size(); iter++)
|
for(size_t iter = 0; iter < buff.size(); iter++)
|
||||||
compressed[iter / 8] |= (buff[iter] << (iter % 8));
|
compressed[iter / 8] |= (buff[iter] << (iter % 8));
|
||||||
|
|
||||||
return {compressed, profile};
|
return {compressLinear(compressed), profile};
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedVoxels compressVoxels(const std::vector<VoxelCube>& voxels, bool fast) {
|
CompressedVoxels compressVoxels(const std::vector<VoxelCube>& voxels, bool fast) {
|
||||||
@@ -419,10 +423,11 @@ std::vector<VoxelCube> unCompressVoxels_bit(const std::u8string& compressed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VoxelCube> unCompressVoxels(const std::u8string& compressed) {
|
std::vector<VoxelCube> unCompressVoxels(const std::u8string& compressed) {
|
||||||
if(compressed.front())
|
const std::u8string& next = unCompressLinear(compressed);
|
||||||
return unCompressVoxels_byte(compressed);
|
if(next.front())
|
||||||
|
return unCompressVoxels_byte(next);
|
||||||
else
|
else
|
||||||
return unCompressVoxels_bit(compressed);
|
return unCompressVoxels_bit(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -510,7 +515,7 @@ CompressedNodes compressNodes_byte(const Node* nodes) {
|
|||||||
|
|
||||||
profiles.shrink_to_fit();
|
profiles.shrink_to_fit();
|
||||||
|
|
||||||
return {compressed, profiles};
|
return {compressLinear(compressed), profiles};
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedNodes compressNodes_bit(const Node* nodes) {
|
CompressedNodes compressNodes_bit(const Node* nodes) {
|
||||||
@@ -628,15 +633,33 @@ CompressedNodes compressNodes_bit(const Node* nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {compressed, profiles};
|
return {compressLinear(compressed), profiles};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CompressedNodes compressNodes(const Node* nodes, bool fast) {
|
CompressedNodes compressNodes(const Node* nodes, bool fast) {
|
||||||
if(fast)
|
std::u8string data(16*16*16*sizeof(Node), '\0');
|
||||||
return compressNodes_byte(nodes);
|
const char8_t *ptr = (const char8_t*) nodes;
|
||||||
else
|
std::copy(ptr, ptr+16*16*16*4, data.data());
|
||||||
return compressNodes_bit(nodes);
|
|
||||||
|
std::vector<DefNodeId_t> node(16*16*16);
|
||||||
|
for(int iter = 0; iter < 16*16*16; iter++) {
|
||||||
|
node[iter] = nodes[iter].NodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::sort(node.begin(), node.end());
|
||||||
|
auto last = std::unique(node.begin(), node.end());
|
||||||
|
node.erase(last, node.end());
|
||||||
|
node.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {compressLinear(data), std::move(node)};
|
||||||
|
|
||||||
|
// if(fast)
|
||||||
|
// return compressNodes_byte(nodes);
|
||||||
|
// else
|
||||||
|
// return compressNodes_bit(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unCompressNodes_byte(const std::u8string& compressed, Node* ptr) {
|
void unCompressNodes_byte(const std::u8string& compressed, Node* ptr) {
|
||||||
@@ -761,10 +784,44 @@ void unCompressNodes_bit(const std::u8string& compressed, Node* ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void unCompressNodes(const std::u8string& compressed, Node* ptr) {
|
void unCompressNodes(const std::u8string& compressed, Node* ptr) {
|
||||||
if(compressed.front())
|
const std::u8string& next = unCompressLinear(compressed);
|
||||||
return unCompressNodes_byte(compressed, ptr);
|
const Node *lPtr = (const Node*) next.data();
|
||||||
else
|
std::copy(lPtr, lPtr+16*16*16, ptr);
|
||||||
return unCompressNodes_bit(compressed, ptr);
|
|
||||||
|
// if(next.front())
|
||||||
|
// return unCompressNodes_byte(next, ptr);
|
||||||
|
// else
|
||||||
|
// return unCompressNodes_bit(next, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::u8string compressLinear(const std::u8string& data) {
|
||||||
|
std::stringstream in;
|
||||||
|
in.write((const char*) data.data(), data.size());
|
||||||
|
|
||||||
|
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
|
||||||
|
out.push(boost::iostreams::zlib_compressor());
|
||||||
|
out.push(in);
|
||||||
|
|
||||||
|
std::stringstream compressed;
|
||||||
|
boost::iostreams::copy(out, compressed);
|
||||||
|
std::string outString = compressed.str();
|
||||||
|
|
||||||
|
return *(std::u8string*) &outString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::u8string unCompressLinear(const std::u8string& data) {
|
||||||
|
std::stringstream in;
|
||||||
|
in.write((const char*) data.data(), data.size());
|
||||||
|
|
||||||
|
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
|
||||||
|
out.push(boost::iostreams::zlib_decompressor());
|
||||||
|
out.push(in);
|
||||||
|
|
||||||
|
std::stringstream compressed;
|
||||||
|
boost::iostreams::copy(out, compressed);
|
||||||
|
std::string outString = compressed.str();
|
||||||
|
|
||||||
|
return *(std::u8string*) &outString;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/Net.hpp"
|
#include "Common/Net.hpp"
|
||||||
|
#include "TOSLib.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
@@ -90,7 +91,7 @@ public:
|
|||||||
using U = std::make_unsigned_t<T>;
|
using U = std::make_unsigned_t<T>;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++) {
|
for(size_t iter = 0; iter < N; iter++) {
|
||||||
out |= Pack(U(get(iter))) << BitsPerComponent*iter;
|
out |= Pack(U(get(iter)) & U((Pack(1) << BitsPerComponent)-1)) << BitsPerComponent*iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@@ -100,7 +101,7 @@ public:
|
|||||||
using U = std::make_unsigned_t<T>;
|
using U = std::make_unsigned_t<T>;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++) {
|
for(size_t iter = 0; iter < N; iter++) {
|
||||||
set(iter, U((pack >> BitsPerComponent*iter) & ((Pack(1) << BitsPerComponent)-1)));
|
set(iter, T(U((pack >> BitsPerComponent*iter) & U((Pack(1) << BitsPerComponent)-1))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,6 +482,9 @@ struct CompressedNodes {
|
|||||||
CompressedNodes compressNodes(const Node* nodes, bool fast = true);
|
CompressedNodes compressNodes(const Node* nodes, bool fast = true);
|
||||||
void unCompressNodes(const std::u8string& compressed, Node* ptr);
|
void unCompressNodes(const std::u8string& compressed, Node* ptr);
|
||||||
|
|
||||||
|
std::u8string compressLinear(const std::u8string& data);
|
||||||
|
std::u8string unCompressLinear(const std::u8string& data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ struct PacketQuat {
|
|||||||
0 -
|
0 -
|
||||||
1 -
|
1 -
|
||||||
2 - Новая позиция камеры WorldId_c+ObjectPos+PacketQuat
|
2 - Новая позиция камеры WorldId_c+ObjectPos+PacketQuat
|
||||||
|
3 - Изменение блока
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -74,7 +75,8 @@ enum struct L1 : uint8_t {
|
|||||||
enum struct L2System : uint8_t {
|
enum struct L2System : uint8_t {
|
||||||
InitEnd,
|
InitEnd,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
Test_CAM_PYR_POS
|
Test_CAM_PYR_POS,
|
||||||
|
BlockChange
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,26 @@ void ContentEventController::onUpdate() {
|
|||||||
if(r1 != r2) {
|
if(r1 != r2) {
|
||||||
CrossedBorder = true;
|
CrossedBorder = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!Remote->Actions.get_read().empty()) {
|
||||||
|
auto lock = Remote->Actions.lock();
|
||||||
|
while(!lock->empty()) {
|
||||||
|
uint8_t action = lock->front();
|
||||||
|
lock->pop();
|
||||||
|
|
||||||
|
Pos::GlobalNode pos = (Pos::GlobalNode) (glm::vec3) (glm::mat4(Remote->CameraQuat.toQuat())*glm::vec4(0, 0, -1, 1));
|
||||||
|
pos = Pos.ObjectPos >> Pos::Object_t::BS_Bit;
|
||||||
|
|
||||||
|
if(action == 0) {
|
||||||
|
// Break
|
||||||
|
Break.push(pos);
|
||||||
|
|
||||||
|
} else if(action == 1) {
|
||||||
|
// Build
|
||||||
|
Build.push(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <queue>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -57,10 +58,6 @@ struct ContentViewInfo {
|
|||||||
if(iterWorld == obj.Regions.end()) {
|
if(iterWorld == obj.Regions.end()) {
|
||||||
out.WorldsNew.push_back(key);
|
out.WorldsNew.push_back(key);
|
||||||
out.RegionsNew[key] = regions;
|
out.RegionsNew[key] = regions;
|
||||||
|
|
||||||
for(const Pos::GlobalRegion& rp : regions) {
|
|
||||||
TOS::Logger("New").debug() << rp.x << ' ' << rp.y << ' ' << rp.z;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto &vec = out.RegionsNew[key];
|
auto &vec = out.RegionsNew[key];
|
||||||
vec.reserve(8*8);
|
vec.reserve(8*8);
|
||||||
@@ -69,10 +66,6 @@ struct ContentViewInfo {
|
|||||||
iterWorld->second.begin(), iterWorld->second.end(),
|
iterWorld->second.begin(), iterWorld->second.end(),
|
||||||
std::back_inserter(vec)
|
std::back_inserter(vec)
|
||||||
);
|
);
|
||||||
|
|
||||||
for(Pos::GlobalRegion& rp : vec) {
|
|
||||||
TOS::Logger("New").debug() << rp.x << ' ' << rp.y << ' ' << rp.z;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +76,6 @@ struct ContentViewInfo {
|
|||||||
if(iterWorld == Regions.end()) {
|
if(iterWorld == Regions.end()) {
|
||||||
out.WorldsLost.push_back(key);
|
out.WorldsLost.push_back(key);
|
||||||
out.RegionsLost[key] = regions;
|
out.RegionsLost[key] = regions;
|
||||||
|
|
||||||
for(const Pos::GlobalRegion& rp : regions) {
|
|
||||||
TOS::Logger("Lost").debug() << rp.x << ' ' << rp.y << ' ' << rp.z;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto &vec = out.RegionsLost[key];
|
auto &vec = out.RegionsLost[key];
|
||||||
vec.reserve(8*8);
|
vec.reserve(8*8);
|
||||||
@@ -95,10 +84,6 @@ struct ContentViewInfo {
|
|||||||
iterWorld->second.begin(), iterWorld->second.end(),
|
iterWorld->second.begin(), iterWorld->second.end(),
|
||||||
std::back_inserter(vec)
|
std::back_inserter(vec)
|
||||||
);
|
);
|
||||||
|
|
||||||
for(Pos::GlobalRegion& rp : vec) {
|
|
||||||
TOS::Logger("Lost").debug() << rp.x << ' ' << rp.y << ' ' << rp.z;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +138,7 @@ public:
|
|||||||
bool CrossedBorder = true;
|
bool CrossedBorder = true;
|
||||||
|
|
||||||
ServerObjectPos Pos, LastPos;
|
ServerObjectPos Pos, LastPos;
|
||||||
|
std::queue<Pos::GlobalNode> Build, Break;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContentEventController(std::unique_ptr<RemoteClient>&& remote);
|
ContentEventController(std::unique_ptr<RemoteClient>&& remote);
|
||||||
|
|||||||
@@ -29,18 +29,18 @@ GameServer::GameServer(asio::io_context &ioc, fs::path worldPath)
|
|||||||
{
|
{
|
||||||
init(worldPath);
|
init(worldPath);
|
||||||
|
|
||||||
BackingChunkPressure.Threads.resize(1);
|
BackingChunkPressure.Threads.resize(4);
|
||||||
BackingChunkPressure.Worlds = &Expanse.Worlds;
|
BackingChunkPressure.Worlds = &Expanse.Worlds;
|
||||||
for(size_t iter = 0; iter < BackingChunkPressure.Threads.size(); iter++) {
|
for(size_t iter = 0; iter < BackingChunkPressure.Threads.size(); iter++) {
|
||||||
BackingChunkPressure.Threads[iter] = std::thread(&BackingChunkPressure_t::run, &BackingChunkPressure, iter);
|
BackingChunkPressure.Threads[iter] = std::thread(&BackingChunkPressure_t::run, &BackingChunkPressure, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackingNoiseGenerator.Threads.resize(1);
|
BackingNoiseGenerator.Threads.resize(4);
|
||||||
for(size_t iter = 0; iter < BackingNoiseGenerator.Threads.size(); iter++) {
|
for(size_t iter = 0; iter < BackingNoiseGenerator.Threads.size(); iter++) {
|
||||||
BackingNoiseGenerator.Threads[iter] = std::thread(&BackingNoiseGenerator_t::run, &BackingNoiseGenerator, iter);
|
BackingNoiseGenerator.Threads[iter] = std::thread(&BackingNoiseGenerator_t::run, &BackingNoiseGenerator, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackingAsyncLua.Threads.resize(2);
|
BackingAsyncLua.Threads.resize(4);
|
||||||
for(size_t iter = 0; iter < BackingAsyncLua.Threads.size(); iter++) {
|
for(size_t iter = 0; iter < BackingAsyncLua.Threads.size(); iter++) {
|
||||||
BackingAsyncLua.Threads[iter] = std::thread(&BackingAsyncLua_t::run, &BackingAsyncLua, iter);
|
BackingAsyncLua.Threads[iter] = std::thread(&BackingAsyncLua_t::run, &BackingAsyncLua, iter);
|
||||||
}
|
}
|
||||||
@@ -65,17 +65,23 @@ GameServer::~GameServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameServer::BackingChunkPressure_t::run(int id) {
|
void GameServer::BackingChunkPressure_t::run(int id) {
|
||||||
|
// static thread_local int local_counter = -1;
|
||||||
|
int iteration = 0;
|
||||||
LOG.debug() << "Старт потока " << id;
|
LOG.debug() << "Старт потока " << id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while(true) {
|
while(true) {
|
||||||
|
// local_counter++;
|
||||||
|
// LOG.debug() << "Ожидаю начала " << id << ' ' << local_counter;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(Mutex);
|
std::unique_lock<std::mutex> lock(Mutex);
|
||||||
Symaphore.wait(lock, [&](){ return RunCollect != 0 || NeedShutdown; });
|
Symaphore.wait(lock, [&](){ return iteration != Iteration || NeedShutdown; });
|
||||||
if(NeedShutdown) {
|
if(NeedShutdown) {
|
||||||
LOG.debug() << "Завершение выполнения потока " << id;
|
LOG.debug() << "Завершение выполнения потока " << id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iteration = Iteration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сбор данных
|
// Сбор данных
|
||||||
@@ -97,20 +103,19 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
|
|
||||||
for(const auto& [regionPos, region] : worldObj.Regions) {
|
for(const auto& [regionPos, region] : worldObj.Regions) {
|
||||||
auto& regionObj = *region;
|
auto& regionObj = *region;
|
||||||
if(counter++ % pullSize != 0) {
|
if(counter++ % pullSize != id) {
|
||||||
counter %= pullSize;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dump dumpRegion;
|
Dump dumpRegion;
|
||||||
|
|
||||||
|
dumpRegion.CECs = regionObj.CECs;
|
||||||
dumpRegion.IsChunkChanged_Voxels = regionObj.IsChunkChanged_Voxels;
|
dumpRegion.IsChunkChanged_Voxels = regionObj.IsChunkChanged_Voxels;
|
||||||
regionObj.IsChunkChanged_Voxels = 0;
|
regionObj.IsChunkChanged_Voxels = 0;
|
||||||
dumpRegion.IsChunkChanged_Nodes = regionObj.IsChunkChanged_Nodes;
|
dumpRegion.IsChunkChanged_Nodes = regionObj.IsChunkChanged_Nodes;
|
||||||
regionObj.IsChunkChanged_Nodes = 0;
|
regionObj.IsChunkChanged_Nodes = 0;
|
||||||
|
|
||||||
if(!regionObj.NewCECs.empty()) {
|
if(!regionObj.NewCECs.empty()) {
|
||||||
dumpRegion.CECs = regionObj.CECs;
|
|
||||||
dumpRegion.NewCECs = std::move(regionObj.NewCECs);
|
dumpRegion.NewCECs = std::move(regionObj.NewCECs);
|
||||||
dumpRegion.Voxels = regionObj.Voxels;
|
dumpRegion.Voxels = regionObj.Voxels;
|
||||||
|
|
||||||
@@ -123,9 +128,9 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
std::copy(fromPtr, fromPtr+16*16*16, toPtr.data());
|
std::copy(fromPtr, fromPtr+16*16*16, toPtr.data());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(regionObj.IsChunkChanged_Voxels) {
|
if(dumpRegion.IsChunkChanged_Voxels) {
|
||||||
for(int index = 0; index < 64; index++) {
|
for(int index = 0; index < 64; index++) {
|
||||||
if((regionObj.IsChunkChanged_Voxels >> index) & 0x1)
|
if(((dumpRegion.IsChunkChanged_Voxels >> index) & 0x1) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pos::bvec4u chunkPos;
|
Pos::bvec4u chunkPos;
|
||||||
@@ -140,9 +145,9 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regionObj.IsChunkChanged_Nodes) {
|
if(dumpRegion.IsChunkChanged_Nodes) {
|
||||||
for(int index = 0; index < 64; index++) {
|
for(int index = 0; index < 64; index++) {
|
||||||
if((regionObj.IsChunkChanged_Nodes >> index) & 0x1)
|
if(((dumpRegion.IsChunkChanged_Nodes >> index) & 0x1) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pos::bvec4u chunkPos;
|
Pos::bvec4u chunkPos;
|
||||||
@@ -166,9 +171,10 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Синхронизация
|
// Синхронизация
|
||||||
|
// LOG.debug() << "Синхронизирую " << id << ' ' << local_counter;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(Mutex);
|
std::unique_lock<std::mutex> lock(Mutex);
|
||||||
RunCollect--;
|
RunCollect -= 1;
|
||||||
Symaphore.notify_all();
|
Symaphore.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +213,7 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
if((region.IsChunkChanged_Voxels >> chunkPos.pack()) & 0x1) {
|
if((region.IsChunkChanged_Voxels >> chunkPos.pack()) & 0x1) {
|
||||||
for(auto& ptr : region.CECs) {
|
for(auto& ptr : region.CECs) {
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for(auto& ptr2 : region.CECs) {
|
for(auto& ptr2 : region.NewCECs) {
|
||||||
if(ptr == ptr2) {
|
if(ptr == ptr2) {
|
||||||
skip = true;
|
skip = true;
|
||||||
break;
|
break;
|
||||||
@@ -246,7 +252,7 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
if((region.IsChunkChanged_Nodes >> chunkPos.pack()) & 0x1) {
|
if((region.IsChunkChanged_Nodes >> chunkPos.pack()) & 0x1) {
|
||||||
for(auto& ptr : region.CECs) {
|
for(auto& ptr : region.CECs) {
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for(auto& ptr2 : region.CECs) {
|
for(auto& ptr2 : region.NewCECs) {
|
||||||
if(ptr == ptr2) {
|
if(ptr == ptr2) {
|
||||||
skip = true;
|
skip = true;
|
||||||
break;
|
break;
|
||||||
@@ -315,9 +321,10 @@ void GameServer::BackingChunkPressure_t::run(int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Синхронизация
|
// Синхронизация
|
||||||
|
// LOG.debug() << "Конец " << id << ' ' << local_counter;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(Mutex);
|
std::unique_lock<std::mutex> lock(Mutex);
|
||||||
RunCompress--;
|
RunCompress -= 1;
|
||||||
Symaphore.notify_all();
|
Symaphore.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,7 +371,9 @@ void GameServer::BackingNoiseGenerator_t::run(int id) {
|
|||||||
for(int z = 0; z < 64; z++)
|
for(int z = 0; z < 64; z++)
|
||||||
for(int y = 0; y < 64; y++)
|
for(int y = 0; y < 64; y++)
|
||||||
for(int x = 0; x < 64; x++, ptr++) {
|
for(int x = 0; x < 64; x++, ptr++) {
|
||||||
*ptr = TOS::genRand(); //glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z));
|
// *ptr = TOS::genRand();
|
||||||
|
*ptr = glm::perlin(glm::vec3(posNode.x+x, posNode.y+y, posNode.z+z) / 16.13f);
|
||||||
|
//*ptr = std::pow(*ptr, 0.75f)*1.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output.lock()->push_back({key, std::move(data)});
|
Output.lock()->push_back({key, std::move(data)});
|
||||||
@@ -403,15 +412,17 @@ void GameServer::BackingAsyncLua_t::run(int id) {
|
|||||||
lock->pop();
|
lock->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if(key.RegionPos == Pos::GlobalRegion(0, 0, 0))
|
||||||
{
|
{
|
||||||
|
float *ptr = noise.data();
|
||||||
for(int z = 0; z < 64; z++)
|
for(int z = 0; z < 64; z++)
|
||||||
for(int y = 0; y < 64; y++)
|
for(int y = 0; y < 64; y++)
|
||||||
for(int x = 0; x < 64; x++) {
|
for(int x = 0; x < 64; x++, ptr++) {
|
||||||
// DefVoxelId_t id = *ptr > 0.9 ? 1 : 0;
|
DefVoxelId_t id = std::clamp(*ptr, 0.f, 1.f) * 3; //> 0.9 ? 1 : 0;
|
||||||
Pos::bvec64u nodePos(x, y, z);
|
Pos::bvec64u nodePos(x, y, z);
|
||||||
auto &node = out.Nodes[Pos::bvec4u(nodePos >> 4).pack()][Pos::bvec16u(nodePos & 0xf).pack()];
|
auto &node = out.Nodes[Pos::bvec4u(nodePos >> 4).pack()][Pos::bvec16u(nodePos & 0xf).pack()];
|
||||||
// node.NodeId = id;
|
node.NodeId = id;
|
||||||
// node.Meta = 0;
|
node.Meta = 0;
|
||||||
|
|
||||||
if(x == 0 && z == 0)
|
if(x == 0 && z == 0)
|
||||||
node.NodeId = 1;
|
node.NodeId = 1;
|
||||||
@@ -419,12 +430,21 @@ void GameServer::BackingAsyncLua_t::run(int id) {
|
|||||||
node.NodeId = 2;
|
node.NodeId = 2;
|
||||||
else if(x == 0 && y == 0)
|
else if(x == 0 && y == 0)
|
||||||
node.NodeId = 3;
|
node.NodeId = 3;
|
||||||
else
|
|
||||||
|
if(y == 1 && z == 0)
|
||||||
|
node.NodeId = 0;
|
||||||
|
else if(x == 0 && y == 1)
|
||||||
node.NodeId = 0;
|
node.NodeId = 0;
|
||||||
|
|
||||||
node.Meta = 0;
|
// node.Meta = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// Node *ptr = (Node*) &out.Nodes[0][0];
|
||||||
|
// Node node;
|
||||||
|
// node.Data = 0;
|
||||||
|
// std::fill(ptr, ptr+64*64*64, node);
|
||||||
|
// }
|
||||||
|
|
||||||
RegionOut.lock()->push_back({key, out});
|
RegionOut.lock()->push_back({key, out});
|
||||||
}
|
}
|
||||||
@@ -799,7 +819,7 @@ void GameServer::stepConnections() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameServer::stepModInitializations() {
|
void GameServer::stepModInitializations() {
|
||||||
|
BackingChunkPressure.endWithResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
IWorldSaveBackend::TickSyncInfo_Out GameServer::stepDatabaseSync() {
|
IWorldSaveBackend::TickSyncInfo_Out GameServer::stepDatabaseSync() {
|
||||||
@@ -1422,6 +1442,32 @@ void GameServer::stepGlobalStep() {
|
|||||||
void GameServer::stepSyncContent() {
|
void GameServer::stepSyncContent() {
|
||||||
for(std::shared_ptr<ContentEventController>& cec : Game.CECs) {
|
for(std::shared_ptr<ContentEventController>& cec : Game.CECs) {
|
||||||
cec->onUpdate();
|
cec->onUpdate();
|
||||||
|
|
||||||
|
while(!cec->Build.empty()) {
|
||||||
|
Pos::GlobalNode node = cec->Build.front();
|
||||||
|
cec->Build.pop();
|
||||||
|
|
||||||
|
Pos::GlobalRegion rPos = node >> 6;
|
||||||
|
Pos::bvec4u cPos = (node >> 4) & 0x3;
|
||||||
|
Pos::bvec16u nPos = node & 0xf;
|
||||||
|
|
||||||
|
auto ®ion = Expanse.Worlds[0]->Regions[rPos];
|
||||||
|
region->Nodes[cPos.pack()][nPos.pack()].NodeId = 4;
|
||||||
|
region->IsChunkChanged_Nodes |= 1ull << cPos.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!cec->Break.empty()) {
|
||||||
|
Pos::GlobalNode node = cec->Break.front();
|
||||||
|
cec->Break.pop();
|
||||||
|
|
||||||
|
Pos::GlobalRegion rPos = node >> 6;
|
||||||
|
Pos::bvec4u cPos = (node >> 4) & 0x3;
|
||||||
|
Pos::bvec16u nPos = node & 0xf;
|
||||||
|
|
||||||
|
auto ®ion = Expanse.Worlds[0]->Regions[rPos];
|
||||||
|
region->Nodes[cPos.pack()][nPos.pack()].NodeId = 0;
|
||||||
|
region->IsChunkChanged_Nodes |= 1ull << cPos.pack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Оповещения о ресурсах и профилях
|
// Оповещения о ресурсах и профилях
|
||||||
|
|||||||
@@ -145,16 +145,18 @@ class GameServer : public AsyncObject {
|
|||||||
*/
|
*/
|
||||||
struct BackingChunkPressure_t {
|
struct BackingChunkPressure_t {
|
||||||
TOS::Logger LOG = "BackingChunkPressure";
|
TOS::Logger LOG = "BackingChunkPressure";
|
||||||
bool NeedShutdown = false;
|
volatile bool NeedShutdown = false;
|
||||||
std::vector<std::thread> Threads;
|
std::vector<std::thread> Threads;
|
||||||
std::mutex Mutex;
|
std::mutex Mutex;
|
||||||
int RunCollect = 0, RunCompress = 0;
|
volatile int RunCollect = 0, RunCompress = 0, Iteration = 0;
|
||||||
std::condition_variable Symaphore;
|
std::condition_variable Symaphore;
|
||||||
std::unordered_map<WorldId_t, std::unique_ptr<World>> *Worlds;
|
std::unordered_map<WorldId_t, std::unique_ptr<World>> *Worlds;
|
||||||
|
|
||||||
void startCollectChanges() {
|
void startCollectChanges() {
|
||||||
std::lock_guard<std::mutex> lock(Mutex);
|
std::lock_guard<std::mutex> lock(Mutex);
|
||||||
RunCompress = RunCollect = Threads.size();
|
RunCollect = Threads.size();
|
||||||
|
RunCompress = Threads.size();
|
||||||
|
Iteration += 1;
|
||||||
Symaphore.notify_all();
|
Symaphore.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
if(iterWorld != ResUses.RefChunk.end())
|
if(iterWorld != ResUses.RefChunk.end())
|
||||||
// Исключим зависимости предыдущей версии чанка
|
// Исключим зависимости предыдущей версии чанка
|
||||||
{
|
{
|
||||||
auto iterRegion = iterWorld->second.find(chunkPos);
|
auto iterRegion = iterWorld->second.find(regionPos);
|
||||||
if(iterRegion != iterWorld->second.end()) {
|
if(iterRegion != iterWorld->second.end()) {
|
||||||
// Уменьшим счётчик зависимостей
|
// Уменьшим счётчик зависимостей
|
||||||
for(const DefVoxelId_t& id : iterRegion->second[localChunk.pack()].Voxel) {
|
for(const DefVoxelId_t& id : iterRegion->second[localChunk.pack()].Voxel) {
|
||||||
@@ -128,6 +128,8 @@ bool RemoteClient::maybe_prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
if(!newTypes.empty()) {
|
if(!newTypes.empty()) {
|
||||||
// Добавляем новые типы в запрос
|
// Добавляем новые типы в запрос
|
||||||
NextRequest.Voxel.insert(NextRequest.Voxel.end(), newTypes.begin(), newTypes.end());
|
NextRequest.Voxel.insert(NextRequest.Voxel.end(), newTypes.begin(), newTypes.end());
|
||||||
|
for(DefVoxelId_t voxel : newTypes)
|
||||||
|
ResUses.RefDefVoxel[voxel] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypes.empty()) {
|
if(!lostTypes.empty()) {
|
||||||
@@ -181,7 +183,7 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global
|
|||||||
if(iterWorld != ResUses.RefChunk.end())
|
if(iterWorld != ResUses.RefChunk.end())
|
||||||
// Исключим зависимости предыдущей версии чанка
|
// Исключим зависимости предыдущей версии чанка
|
||||||
{
|
{
|
||||||
auto iterRegion = iterWorld->second.find(chunkPos);
|
auto iterRegion = iterWorld->second.find(regionPos);
|
||||||
if(iterRegion != iterWorld->second.end()) {
|
if(iterRegion != iterWorld->second.end()) {
|
||||||
// Уменьшим счётчик зависимостей
|
// Уменьшим счётчик зависимостей
|
||||||
for(const DefNodeId_t& id : iterRegion->second[localChunk.pack()].Node) {
|
for(const DefNodeId_t& id : iterRegion->second[localChunk.pack()].Node) {
|
||||||
@@ -204,6 +206,8 @@ bool RemoteClient::maybe_prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::Global
|
|||||||
if(!newTypes.empty()) {
|
if(!newTypes.empty()) {
|
||||||
// Добавляем новые типы в запрос
|
// Добавляем новые типы в запрос
|
||||||
NextRequest.Node.insert(NextRequest.Node.end(), newTypes.begin(), newTypes.end());
|
NextRequest.Node.insert(NextRequest.Node.end(), newTypes.begin(), newTypes.end());
|
||||||
|
for(DefNodeId_t node : newTypes)
|
||||||
|
ResUses.RefDefNode[node] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!lostTypes.empty()) {
|
if(!lostTypes.empty()) {
|
||||||
@@ -259,6 +263,8 @@ void RemoteClient::prepareRegionRemove(WorldId_t worldId, Pos::GlobalRegion regi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterWorld->second.erase(iterRegion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +681,12 @@ coro<> RemoteClient::rP_System(Net::AsyncSocket &sock) {
|
|||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
case ToServer::L2System::BlockChange:
|
||||||
|
{
|
||||||
|
uint8_t action = co_await sock.read<uint8_t>();
|
||||||
|
Actions.lock()->push(action);
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
protocolError();
|
protocolError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -296,6 +297,7 @@ public:
|
|||||||
const std::string Username;
|
const std::string Username;
|
||||||
Pos::Object CameraPos = {0, 0, 0};
|
Pos::Object CameraPos = {0, 0, 0};
|
||||||
ToServer::PacketQuat CameraQuat = {0};
|
ToServer::PacketQuat CameraQuat = {0};
|
||||||
|
TOS::SpinlockObject<std::queue<uint8_t>> Actions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username, std::vector<HASH> &&client_cache)
|
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username, std::vector<HASH> &&client_cache)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
namespace TOS {
|
namespace TOS {
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "Common/Abstract.hpp"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
@@ -20,6 +21,7 @@ int main() {
|
|||||||
|
|
||||||
// LuaVox
|
// LuaVox
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
Logger LOG = "main";
|
||||||
|
|
||||||
LV::Client::VK::Vulkan vkInst(ioc);
|
LV::Client::VK::Vulkan vkInst(ioc);
|
||||||
|
|
||||||
|
|||||||
BIN
assets/textures/0.png
Normal file
BIN
assets/textures/0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.8 KiB |
Reference in New Issue
Block a user