Сейчас оно компилируется, пересмотр расчёта зон наблюдения
This commit is contained in:
@@ -34,7 +34,12 @@ struct GlobalTime {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct VoxelCube {
|
struct VoxelCube {
|
||||||
DefVoxelId_t VoxelId;
|
union {
|
||||||
|
struct {
|
||||||
|
DefVoxelId_t VoxelId : 24, Meta : 8;
|
||||||
|
};
|
||||||
|
DefVoxelId_t Data;
|
||||||
|
};
|
||||||
Pos::bvec256u Left, Size;
|
Pos::bvec256u Left, Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,39 +82,32 @@ public:
|
|||||||
virtual void onBinaryResourceAdd(std::unordered_map<EnumBinResource, std::unordered_map<ResourceId_t, BinaryResource>>) = 0;
|
virtual void onBinaryResourceAdd(std::unordered_map<EnumBinResource, std::unordered_map<ResourceId_t, BinaryResource>>) = 0;
|
||||||
virtual void onBinaryResourceLost(std::unordered_map<EnumBinResource, std::vector<ResourceId_t>>) = 0;
|
virtual void onBinaryResourceLost(std::unordered_map<EnumBinResource, std::vector<ResourceId_t>>) = 0;
|
||||||
|
|
||||||
// Профили использования двоичных ресурсов
|
virtual void onContentDefinesAdd(std::unordered_map<EnumDefContent, std::unordered_map<ResourceId_t, std::u8string>>) = 0;
|
||||||
// В этом месте нужно зарание распарсить
|
virtual void onContentDefinesLost(std::unordered_map<EnumDefContent, std::vector<ResourceId_t>>) = 0;
|
||||||
virtual void onBinaryProfileAdd(std::unordered_map<EnumBinResource, std::unordered_map<ResourceId_t, std::u8string>>) = 0;
|
|
||||||
virtual void onBinaryProfileLost(std::unordered_map<EnumBinResource, std::vector<ResourceId_t>>) = 0;
|
|
||||||
|
|
||||||
virtual void onContentDefines(std::unordered_map<EnumDefContent, std::unordered_map<>>);
|
|
||||||
EnumDefContent
|
|
||||||
|
|
||||||
virtual void onDefWorldUpdates(const std::vector<DefWorldId_c> &updates) = 0;
|
|
||||||
virtual void onDefVoxelUpdates(const std::vector<DefVoxelId_c> &updates) = 0;
|
|
||||||
virtual void onDefNodeUpdates(const std::vector<DefNodeId_c> &updates) = 0;
|
|
||||||
virtual void onDefPortalUpdates(const std::vector<DefPortalId_c> &updates) = 0;
|
|
||||||
virtual void onDefEntityUpdates(const std::vector<DefEntityId_c> &updates) = 0;
|
|
||||||
|
|
||||||
// Сообщаем об изменившихся чанках
|
// Сообщаем об изменившихся чанках
|
||||||
virtual void onChunksChange(WorldId_c worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) = 0;
|
virtual void onChunksChange(WorldId_t worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) = 0;
|
||||||
// Установить позицию для камеры
|
// Установить позицию для камеры
|
||||||
virtual void setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) = 0;
|
virtual void setCameraPos(WorldId_t worldId, Pos::Object pos, glm::quat quat) = 0;
|
||||||
|
|
||||||
virtual ~IRenderSession();
|
virtual ~IRenderSession();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Region {
|
struct Region {
|
||||||
std::unordered_map<Pos::Local16_u, Chunk> Chunks;
|
std::unordered_map<Pos::bvec16u, Chunk> Chunks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct World {
|
struct World {
|
||||||
std::vector<EntityId_c> Entitys;
|
|
||||||
std::unordered_map<Pos::GlobalRegion::Key, Region> Regions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DefVoxelInfo {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefNodeInfo {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct DefWorldInfo {
|
struct DefWorldInfo {
|
||||||
|
|
||||||
@@ -123,10 +121,16 @@ struct DefEntityInfo {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WorldInfo {
|
struct DefFuncEntityInfo {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WorldInfo {
|
||||||
|
std::vector<EntityId_t> Entitys;
|
||||||
|
std::vector<FuncEntityId_t> FuncEntitys;
|
||||||
|
std::unordered_map<Pos::GlobalRegion, Region> Regions;
|
||||||
|
};
|
||||||
|
|
||||||
struct VoxelInfo {
|
struct VoxelInfo {
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -143,24 +147,33 @@ struct EntityInfo {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FuncEntityInfo {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefItemInfo {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/* Интерфейс обработчика сессии с сервером */
|
/* Интерфейс обработчика сессии с сервером */
|
||||||
class IServerSession {
|
class IServerSession {
|
||||||
public:
|
public:
|
||||||
struct {
|
struct {
|
||||||
std::unordered_map<DefWorldId_c, DefWorldInfo> DefWorlds;
|
std::unordered_map<DefVoxelId_t, DefVoxelInfo> DefVoxel;
|
||||||
std::unordered_map<DefVoxelId_c, VoxelInfo> DefVoxels;
|
std::unordered_map<DefNodeId_t, DefNodeInfo> DefNode;
|
||||||
std::unordered_map<DefNodeId_c, NodeInfo> DefNodes;
|
std::unordered_map<DefWorldId_t, DefWorldInfo> DefWorld;
|
||||||
std::unordered_map<DefPortalId_c, DefPortalInfo> DefPortals;
|
std::unordered_map<DefPortalId_t, DefPortalInfo> DefPortal;
|
||||||
std::unordered_map<DefEntityId_c, DefEntityInfo> DefEntityes;
|
std::unordered_map<DefEntityId_t, DefEntityInfo> DefEntity;
|
||||||
|
std::unordered_map<DefFuncEntityId_t, DefFuncEntityInfo> DefFuncEntity;
|
||||||
std::unordered_map<WorldId_c, WorldInfo> Worlds;
|
std::unordered_map<DefItemId_t, DefItemInfo> DefItem;
|
||||||
std::unordered_map<PortalId_c, PortalInfo> Portals;
|
|
||||||
std::unordered_map<EntityId_c, EntityInfo> Entityes;
|
|
||||||
} Registry;
|
} Registry;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::unordered_map<WorldId_c, World> Worlds;
|
std::unordered_map<WorldId_t, WorldInfo> Worlds;
|
||||||
} External;
|
std::unordered_map<PortalId_t, PortalInfo> Portals;
|
||||||
|
std::unordered_map<EntityId_t, EntityInfo> Entityes;
|
||||||
|
std::unordered_map<FuncEntityId_t, FuncEntityInfo> FuncEntityes;
|
||||||
|
} Data;
|
||||||
|
|
||||||
virtual ~IServerSession();
|
virtual ~IServerSession();
|
||||||
|
|
||||||
|
|||||||
@@ -20,20 +20,20 @@ namespace LV::Client {
|
|||||||
ParsedPacket::~ParsedPacket() = default;
|
ParsedPacket::~ParsedPacket() = default;
|
||||||
|
|
||||||
struct PP_Content_ChunkVoxels : public ParsedPacket {
|
struct PP_Content_ChunkVoxels : public ParsedPacket {
|
||||||
WorldId_c Id;
|
WorldId_t Id;
|
||||||
Pos::GlobalChunk Pos;
|
Pos::GlobalChunk Pos;
|
||||||
std::vector<VoxelCube> Cubes;
|
std::vector<VoxelCube> Cubes;
|
||||||
|
|
||||||
PP_Content_ChunkVoxels(ToClient::L1 l1, uint8_t l2, WorldId_c id, Pos::GlobalChunk pos, std::vector<VoxelCube> &&cubes)
|
PP_Content_ChunkVoxels(ToClient::L1 l1, uint8_t l2, WorldId_t id, Pos::GlobalChunk pos, std::vector<VoxelCube> &&cubes)
|
||||||
: ParsedPacket(l1, l2), Id(id), Pos(pos), Cubes(std::move(cubes))
|
: ParsedPacket(l1, l2), Id(id), Pos(pos), Cubes(std::move(cubes))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PP_Content_ChunkRemove : public ParsedPacket {
|
struct PP_Content_ChunkRemove : public ParsedPacket {
|
||||||
WorldId_c Id;
|
WorldId_t Id;
|
||||||
Pos::GlobalChunk Pos;
|
Pos::GlobalChunk Pos;
|
||||||
|
|
||||||
PP_Content_ChunkRemove(ToClient::L1 l1, uint8_t l2, WorldId_c id, Pos::GlobalChunk pos)
|
PP_Content_ChunkRemove(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)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@@ -252,7 +252,7 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
Speed += glm::vec3(0, 1, 0)*float(Keys.SPACE)*mltpl;
|
Speed += glm::vec3(0, 1, 0)*float(Keys.SPACE)*mltpl;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unordered_map<WorldId_c, std::tuple<std::unordered_set<Pos::GlobalChunk>, std::unordered_set<Pos::GlobalChunk>>> changeOrAddList_removeList;
|
std::unordered_map<WorldId_t, std::tuple<std::unordered_set<Pos::GlobalChunk>, std::unordered_set<Pos::GlobalChunk>>> changeOrAddList_removeList;
|
||||||
|
|
||||||
// Пакеты
|
// Пакеты
|
||||||
ParsedPacket *pack;
|
ParsedPacket *pack;
|
||||||
@@ -261,19 +261,19 @@ void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
|
|||||||
ToClient::L2Content l2 = ToClient::L2Content(pack->Level2);
|
ToClient::L2Content l2 = ToClient::L2Content(pack->Level2);
|
||||||
if(l2 == ToClient::L2Content::ChunkVoxels) {
|
if(l2 == ToClient::L2Content::ChunkVoxels) {
|
||||||
PP_Content_ChunkVoxels &p = *dynamic_cast<PP_Content_ChunkVoxels*>(pack);
|
PP_Content_ChunkVoxels &p = *dynamic_cast<PP_Content_ChunkVoxels*>(pack);
|
||||||
Pos::GlobalRegion rPos(p.Pos.X >> 4, p.Pos.Y >> 4, p.Pos.Z >> 4);
|
Pos::GlobalRegion rPos = p.Pos >> 2;
|
||||||
Pos::Local16_u cPos(p.Pos.X & 0xf, p.Pos.Y & 0xf, p.Pos.Z & 0xf);
|
Pos::bvec4u cPos = p.Pos & 0x3;
|
||||||
|
|
||||||
External.Worlds[p.Id].Regions[rPos].Chunks[cPos].Voxels = std::move(p.Cubes);
|
Data.Worlds[p.Id].Regions[rPos].Chunks[cPos].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);
|
||||||
} else if(l2 == ToClient::L2Content::RemoveChunk) {
|
} else if(l2 == ToClient::L2Content::RemoveChunk) {
|
||||||
PP_Content_ChunkRemove &p = *dynamic_cast<PP_Content_ChunkRemove*>(pack);
|
PP_Content_ChunkRemove &p = *dynamic_cast<PP_Content_ChunkRemove*>(pack);
|
||||||
|
|
||||||
Pos::GlobalRegion rPos(p.Pos.X >> 4, p.Pos.Y >> 4, p.Pos.Z >> 4);
|
Pos::GlobalRegion rPos = p.Pos >> 2;
|
||||||
Pos::Local16_u cPos(p.Pos.X & 0xf, p.Pos.Y & 0xf, p.Pos.Z & 0xf);
|
Pos::bvec4u cPos = p.Pos & 0x3;
|
||||||
auto &obj = External.Worlds[p.Id].Regions[rPos].Chunks;
|
auto &obj = Data.Worlds[p.Id].Regions[rPos].Chunks;
|
||||||
auto iter = obj.find(cPos);
|
auto iter = obj.find(cPos);
|
||||||
if(iter != obj.end())
|
if(iter != obj.end())
|
||||||
obj.erase(iter);
|
obj.erase(iter);
|
||||||
@@ -443,22 +443,22 @@ coro<> ServerSession::rP_Definition(Net::AsyncSocket &sock) {
|
|||||||
|
|
||||||
switch((ToClient::L2Definition) second) {
|
switch((ToClient::L2Definition) second) {
|
||||||
case ToClient::L2Definition::World: {
|
case ToClient::L2Definition::World: {
|
||||||
DefWorldId_c cdId = co_await sock.read<DefWorldId_c>();
|
DefWorldId_t cdId = co_await sock.read<DefWorldId_t>();
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
case ToClient::L2Definition::FreeWorld: {
|
case ToClient::L2Definition::FreeWorld: {
|
||||||
DefWorldId_c cdId = co_await sock.read<DefWorldId_c>();
|
DefWorldId_t cdId = co_await sock.read<DefWorldId_t>();
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
case ToClient::L2Definition::Voxel: {
|
case ToClient::L2Definition::Voxel: {
|
||||||
DefVoxelId_c cdId = co_await sock.read<DefVoxelId_c>();
|
DefVoxelId_t cdId = co_await sock.read<DefVoxelId_t>();
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
case ToClient::L2Definition::FreeVoxel: {
|
case ToClient::L2Definition::FreeVoxel: {
|
||||||
DefVoxelId_c cdId = co_await sock.read<DefVoxelId_c>();
|
DefVoxelId_t cdId = co_await sock.read<DefVoxelId_t>();
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
@@ -509,9 +509,9 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
co_return;
|
co_return;
|
||||||
case ToClient::L2Content::ChunkVoxels:
|
case ToClient::L2Content::ChunkVoxels:
|
||||||
{
|
{
|
||||||
WorldId_c wcId = co_await sock.read<WorldId_c>();
|
WorldId_t wcId = co_await sock.read<WorldId_t>();
|
||||||
Pos::GlobalChunk::Key posKey = co_await sock.read<Pos::GlobalChunk::Key>();
|
Pos::GlobalChunk pos;
|
||||||
Pos::GlobalChunk pos = *(Pos::GlobalChunk*) &posKey;
|
pos.unpack(co_await sock.read<Pos::GlobalChunk::Pack>());
|
||||||
|
|
||||||
std::vector<VoxelCube> cubes(co_await sock.read<uint16_t>());
|
std::vector<VoxelCube> cubes(co_await sock.read<uint16_t>());
|
||||||
uint16_t debugCubesCount = cubes.size();
|
uint16_t debugCubesCount = cubes.size();
|
||||||
@@ -522,13 +522,13 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
|
|
||||||
for(size_t iter = 0; iter < cubes.size(); iter++) {
|
for(size_t iter = 0; iter < cubes.size(); iter++) {
|
||||||
VoxelCube &cube = cubes[iter];
|
VoxelCube &cube = cubes[iter];
|
||||||
cube.VoxelId = co_await sock.read<uint16_t>();
|
cube.Data = co_await sock.read<DefVoxelId_t>();
|
||||||
cube.Left.X = co_await sock.read<uint8_t>();
|
cube.Left.x = co_await sock.read<uint8_t>();
|
||||||
cube.Left.Y = co_await sock.read<uint8_t>();
|
cube.Left.y = co_await sock.read<uint8_t>();
|
||||||
cube.Left.Z = co_await sock.read<uint8_t>();
|
cube.Left.z = co_await sock.read<uint8_t>();
|
||||||
cube.Size.X = co_await sock.read<uint8_t>();
|
cube.Size.x = co_await sock.read<uint8_t>();
|
||||||
cube.Size.Y = co_await sock.read<uint8_t>();
|
cube.Size.y = co_await sock.read<uint8_t>();
|
||||||
cube.Size.Z = co_await sock.read<uint8_t>();
|
cube.Size.z = co_await sock.read<uint8_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
PP_Content_ChunkVoxels *packet = new PP_Content_ChunkVoxels(
|
PP_Content_ChunkVoxels *packet = new PP_Content_ChunkVoxels(
|
||||||
@@ -551,9 +551,9 @@ coro<> ServerSession::rP_Content(Net::AsyncSocket &sock) {
|
|||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
case ToClient::L2Content::RemoveChunk: {
|
case ToClient::L2Content::RemoveChunk: {
|
||||||
WorldId_c wcId = co_await sock.read<uint8_t>();
|
WorldId_t wcId = co_await sock.read<uint8_t>();
|
||||||
Pos::GlobalChunk::Key posKey = co_await sock.read<Pos::GlobalChunk::Key>();
|
Pos::GlobalChunk pos;
|
||||||
Pos::GlobalChunk pos = *(Pos::GlobalChunk*) &posKey;
|
pos.unpack(co_await sock.read<Pos::GlobalChunk::Pack>());
|
||||||
|
|
||||||
PP_Content_ChunkRemove *packet = new PP_Content_ChunkRemove(
|
PP_Content_ChunkRemove *packet = new PP_Content_ChunkRemove(
|
||||||
ToClient::L1::Content,
|
ToClient::L1::Content,
|
||||||
|
|||||||
@@ -232,16 +232,16 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
{
|
{
|
||||||
std::vector<VoxelCube> cubes;
|
std::vector<VoxelCube> cubes;
|
||||||
|
|
||||||
cubes.emplace_back(0, Pos::Local256_u{0, 0, 0}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({0, 0, Pos::bvec256u{0, 0, 0}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(1, Pos::Local256_u{255, 0, 0}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({1, 0, Pos::bvec256u{255, 0, 0}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(1, Pos::Local256_u{0, 255, 0}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({1, 0, Pos::bvec256u{0, 255, 0}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(1, Pos::Local256_u{0, 0, 255}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({1, 0, Pos::bvec256u{0, 0, 255}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(2, Pos::Local256_u{255, 255, 0}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({2, 0, Pos::bvec256u{255, 255, 0}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(2, Pos::Local256_u{0, 255, 255}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({2, 0, Pos::bvec256u{0, 255, 255}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(2, Pos::Local256_u{255, 0, 255}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({2, 0, Pos::bvec256u{255, 0, 255}, Pos::bvec256u{0, 0, 0}});
|
||||||
cubes.emplace_back(3, Pos::Local256_u{255, 255, 255}, Pos::Local256_u{0, 0, 0});
|
cubes.push_back({3, 0, Pos::bvec256u{255, 255, 255}, Pos::bvec256u{0, 0, 0}});
|
||||||
|
|
||||||
cubes.emplace_back(4, Pos::Local256_u{64, 64, 64}, Pos::Local256_u{127, 127, 127});
|
cubes.push_back({4, 0, Pos::bvec256u{64, 64, 64}, Pos::bvec256u{127, 127, 127}});
|
||||||
|
|
||||||
std::vector<VoxelVertexPoint> vertexs = generateMeshForVoxelChunks(cubes);
|
std::vector<VoxelVertexPoint> vertexs = generateMeshForVoxelChunks(cubes);
|
||||||
|
|
||||||
@@ -595,50 +595,30 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onDefTexture(TextureId_c id, std::vector<std::byte> &&info) {
|
void VulkanRenderSession::onBinaryResourceAdd(std::unordered_map<EnumBinResource, std::unordered_map<ResourceId_t, BinaryResource>>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onDefTextureLost(const std::vector<TextureId_c> &&lost) {
|
void VulkanRenderSession::onBinaryResourceLost(std::unordered_map<EnumBinResource, std::vector<ResourceId_t>>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onDefModel(ModelId_c id, std::vector<std::byte> &&info) {
|
void VulkanRenderSession::onContentDefinesAdd(std::unordered_map<EnumDefContent, std::unordered_map<ResourceId_t, std::u8string>>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onDefModelLost(const std::vector<ModelId_c> &&lost) {
|
void VulkanRenderSession::onContentDefinesLost(std::unordered_map<EnumDefContent, std::vector<ResourceId_t>>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::onDefWorldUpdates(const std::vector<DefWorldId_c> &updates) {
|
void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) {
|
||||||
|
auto &table = External.ChunkVoxelMesh[worldId];
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderSession::onDefVoxelUpdates(const std::vector<DefVoxelId_c> &updates) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderSession::onDefNodeUpdates(const std::vector<DefNodeId_c> &updates) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderSession::onDefPortalUpdates(const std::vector<DefPortalId_c> &updates) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderSession::onDefEntityUpdates(const std::vector<DefEntityId_c> &updates) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderSession::onChunksChange(WorldId_c worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) {
|
|
||||||
auto &table = External.ChunkVoxelMesh[worldId];
|
|
||||||
|
|
||||||
for(Pos::GlobalChunk pos : changeOrAddList) {
|
for(Pos::GlobalChunk pos : changeOrAddList) {
|
||||||
Pos::GlobalRegion rPos(pos.X >> 4, pos.Y >> 4, pos.Z >> 4);
|
Pos::GlobalRegion rPos = pos >> 4;
|
||||||
Pos::Local16_u cPos(pos.X & 0xf, pos.Y & 0xf, pos.Z & 0xf);
|
Pos::bvec16u cPos = pos & 0xf;
|
||||||
|
|
||||||
const auto &voxels = ServerSession->External.Worlds[worldId].Regions[rPos].Chunks[cPos].Voxels;
|
const auto &voxels = ServerSession->Data.Worlds[worldId].Regions[rPos].Chunks[cPos].Voxels;
|
||||||
|
|
||||||
if(voxels.empty()) {
|
if(voxels.empty()) {
|
||||||
auto iter = table.find(pos);
|
auto iter = table.find(pos);
|
||||||
@@ -669,7 +649,7 @@ void VulkanRenderSession::onChunksChange(WorldId_c worldId, const std::unordered
|
|||||||
External.ChunkVoxelMesh.erase( External.ChunkVoxelMesh.find(worldId));
|
External.ChunkVoxelMesh.erase( External.ChunkVoxelMesh.find(worldId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) {
|
void VulkanRenderSession::setCameraPos(WorldId_t worldId, Pos::Object pos, glm::quat quat) {
|
||||||
WorldId = worldId;
|
WorldId = worldId;
|
||||||
Pos = pos;
|
Pos = pos;
|
||||||
Quat = quat;
|
Quat = quat;
|
||||||
@@ -738,7 +718,7 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
glm::mat4 orig = PCO.Model;
|
glm::mat4 orig = PCO.Model;
|
||||||
|
|
||||||
for(auto &pair : iterWorld->second) {
|
for(auto &pair : iterWorld->second) {
|
||||||
glm::vec3 cpos(pair.first.X, pair.first.Y, pair.first.Z);
|
glm::vec3 cpos(pair.first.x, pair.first.y, pair.first.z);
|
||||||
PCO.Model = glm::translate(orig, cpos*16.f);
|
PCO.Model = glm::translate(orig, cpos*16.f);
|
||||||
vkBuffer = *pair.second;
|
vkBuffer = *pair.second;
|
||||||
|
|
||||||
@@ -759,78 +739,78 @@ std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(co
|
|||||||
|
|
||||||
for(const VoxelCube &cube : cubes) {
|
for(const VoxelCube &cube : cubes) {
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X,
|
cube.Left.x,
|
||||||
cube.Left.Y,
|
cube.Left.y,
|
||||||
cube.Left.Z,
|
cube.Left.z,
|
||||||
0,
|
0,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.X,
|
cube.Size.x,
|
||||||
cube.Size.Z,
|
cube.Size.z,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X,
|
cube.Left.x,
|
||||||
cube.Left.Y,
|
cube.Left.y,
|
||||||
cube.Left.Z,
|
cube.Left.z,
|
||||||
1,
|
1,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.X,
|
cube.Size.x,
|
||||||
cube.Size.Y,
|
cube.Size.y,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X,
|
cube.Left.x,
|
||||||
cube.Left.Y,
|
cube.Left.y,
|
||||||
cube.Left.Z,
|
cube.Left.z,
|
||||||
2,
|
2,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.Z,
|
cube.Size.z,
|
||||||
cube.Size.Y,
|
cube.Size.y,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X,
|
cube.Left.x,
|
||||||
cube.Left.Y+cube.Size.Y+1,
|
cube.Left.y+cube.Size.y+1,
|
||||||
cube.Left.Z,
|
cube.Left.z,
|
||||||
3,
|
3,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.X,
|
cube.Size.x,
|
||||||
cube.Size.Z,
|
cube.Size.z,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X,
|
cube.Left.x,
|
||||||
cube.Left.Y,
|
cube.Left.y,
|
||||||
cube.Left.Z+cube.Size.Z+1,
|
cube.Left.z+cube.Size.z+1,
|
||||||
4,
|
4,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.X,
|
cube.Size.x,
|
||||||
cube.Size.Y,
|
cube.Size.y,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
out.emplace_back(
|
out.emplace_back(
|
||||||
cube.Left.X+cube.Size.X+1,
|
cube.Left.x+cube.Size.x+1,
|
||||||
cube.Left.Y,
|
cube.Left.y,
|
||||||
cube.Left.Z,
|
cube.Left.z,
|
||||||
5,
|
5,
|
||||||
0, 0,
|
0, 0,
|
||||||
cube.Size.Z,
|
cube.Size.z,
|
||||||
cube.Size.Y,
|
cube.Size.y,
|
||||||
cube.VoxelId,
|
cube.VoxelId,
|
||||||
0, 0,
|
0, 0,
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
IServerSession *ServerSession = nullptr;
|
IServerSession *ServerSession = nullptr;
|
||||||
|
|
||||||
// Положение камеры
|
// Положение камеры
|
||||||
WorldId_c WorldId;
|
WorldId_t WorldId;
|
||||||
Pos::Object Pos;
|
Pos::Object Pos;
|
||||||
glm::quat Quat;
|
glm::quat Quat;
|
||||||
|
|
||||||
@@ -130,10 +130,10 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
NodeStaticTransparentPipeline = VK_NULL_HANDLE;
|
NodeStaticTransparentPipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
|
||||||
std::map<TextureId_c, uint16_t> ServerToAtlas;
|
std::map<BinTextureId_t, uint16_t> ServerToAtlas;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::unordered_map<WorldId_c, std::unordered_map<Pos::GlobalChunk, std::unique_ptr<Buffer>>> ChunkVoxelMesh;
|
std::unordered_map<WorldId_t, std::unordered_map<Pos::GlobalChunk, std::unique_ptr<Buffer>>> ChunkVoxelMesh;
|
||||||
} External;
|
} External;
|
||||||
|
|
||||||
virtual void free(Vulkan *instance) override;
|
virtual void free(Vulkan *instance) override;
|
||||||
@@ -151,19 +151,12 @@ public:
|
|||||||
assert(serverSession);
|
assert(serverSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onDefTexture(TextureId_c id, std::vector<std::byte> &&info) override;
|
virtual void onBinaryResourceAdd(std::unordered_map<EnumBinResource, std::unordered_map<ResourceId_t, BinaryResource>>) override;
|
||||||
virtual void onDefTextureLost(const std::vector<TextureId_c> &&lost) override;
|
virtual void onBinaryResourceLost(std::unordered_map<EnumBinResource, std::vector<ResourceId_t>>) override;
|
||||||
virtual void onDefModel(ModelId_c id, std::vector<std::byte> &&info) override;
|
virtual void onContentDefinesAdd(std::unordered_map<EnumDefContent, std::unordered_map<ResourceId_t, std::u8string>>) override;
|
||||||
virtual void onDefModelLost(const std::vector<ModelId_c> &&lost) override;
|
virtual void onContentDefinesLost(std::unordered_map<EnumDefContent, std::vector<ResourceId_t>>) override;
|
||||||
|
virtual void onChunksChange(WorldId_t worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) override;
|
||||||
virtual void onDefWorldUpdates(const std::vector<DefWorldId_c> &updates) override;
|
virtual void setCameraPos(WorldId_t worldId, Pos::Object pos, glm::quat quat) override;
|
||||||
virtual void onDefVoxelUpdates(const std::vector<DefVoxelId_c> &updates) override;
|
|
||||||
virtual void onDefNodeUpdates(const std::vector<DefNodeId_c> &updates) override;
|
|
||||||
virtual void onDefPortalUpdates(const std::vector<DefPortalId_c> &updates) override;
|
|
||||||
virtual void onDefEntityUpdates(const std::vector<DefEntityId_c> &updates) override;
|
|
||||||
|
|
||||||
virtual void onChunksChange(WorldId_c worldId, const std::unordered_set<Pos::GlobalChunk> &changeOrAddList, const std::unordered_set<Pos::GlobalChunk> &remove) override;
|
|
||||||
virtual void setCameraPos(WorldId_c worldId, Pos::Object pos, glm::quat quat) override;
|
|
||||||
|
|
||||||
glm::mat4 calcViewMatrix(glm::quat quat, glm::vec3 camOffset = glm::vec3(0)) {
|
glm::mat4 calcViewMatrix(glm::quat quat, glm::vec3 camOffset = glm::vec3(0)) {
|
||||||
return glm::translate(glm::mat4(quat), camOffset);
|
return glm::translate(glm::mat4(quat), camOffset);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
namespace LV {
|
namespace LV {
|
||||||
@@ -42,10 +41,13 @@ public:
|
|||||||
BitVec3() = default;
|
BitVec3() = default;
|
||||||
BitVec3(T value)
|
BitVec3(T value)
|
||||||
: x(value), y(value), z(value)
|
: x(value), y(value), z(value)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
BitVec3(const T x, const T y, const T z)
|
BitVec3(const T x, const T y, const T z)
|
||||||
: x(x), y(y), z(z)
|
: x(x), y(y), z(z)
|
||||||
|
{}
|
||||||
|
template<typename vT, glm::qualifier vQ>
|
||||||
|
BitVec3(const glm::vec<3, vT, vQ> vec)
|
||||||
|
: x(vec.x), y(vec.y), z(vec.z)
|
||||||
{}
|
{}
|
||||||
BitVec3(const BitVec3&) = default;
|
BitVec3(const BitVec3&) = default;
|
||||||
BitVec3(BitVec3&&) = default;
|
BitVec3(BitVec3&&) = default;
|
||||||
@@ -94,7 +96,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++) {
|
||||||
get(iter) = U((pack >> BitsPerComponent*iter) & ((Pack(1) << BitsPerComponent)-1));
|
set(iter, U((pack >> BitsPerComponent*iter) & ((Pack(1) << BitsPerComponent)-1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ public:
|
|||||||
|
|
||||||
template<typename T2, size_t BitsPerComponent2>
|
template<typename T2, size_t BitsPerComponent2>
|
||||||
operator BitVec3<T2, BitsPerComponent2>() const {
|
operator BitVec3<T2, BitsPerComponent2>() const {
|
||||||
BitVec3<T, BitsPerComponent2> out;
|
BitVec3<T2, BitsPerComponent2> out;
|
||||||
for(size_t iter = 0; iter < N; iter++) {
|
for(size_t iter = 0; iter < N; iter++) {
|
||||||
out.set(iter, T2(std::make_unsigned_t<T2>(std::make_unsigned_t<T>(get(iter)))));
|
out.set(iter, T2(std::make_unsigned_t<T2>(std::make_unsigned_t<T>(get(iter)))));
|
||||||
}
|
}
|
||||||
@@ -110,18 +112,24 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename vT, glm::qualifier vQ>
|
||||||
|
operator glm::vec<3, vT, vQ>() const {
|
||||||
|
return {x, y, z};
|
||||||
|
}
|
||||||
|
|
||||||
BitVec3 operator+(const BitVec3 &other) const {
|
BitVec3 operator+(const BitVec3 &other) const {
|
||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) + other[iter];
|
out.set(iter, get(iter) + other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator+=(const BitVec3 &other) {
|
BitVec3& operator+=(const BitVec3 &other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) += other[iter];
|
set(iter, get(iter) + other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -130,14 +138,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) + value;
|
out.set(iter, get(iter) + value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator+=(const T value) {
|
BitVec3& operator+=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) += value;
|
set(iter, get(iter) + value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -146,14 +154,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) - other[iter];
|
out.set(iter, get(iter) - other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator-=(const BitVec3 &other) {
|
BitVec3& operator-=(const BitVec3 &other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) -= other[iter];
|
set(iter, get(iter) - other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -162,14 +170,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) - value;
|
out.set(iter, get(iter) - value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator-=(const T value) {
|
BitVec3& operator-=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) -= value;
|
set(iter, get(iter) - value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -178,14 +186,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) * other[iter];
|
out.set(iter, get(iter) * other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator*=(const BitVec3 &other) {
|
BitVec3& operator*=(const BitVec3 &other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) *= other[iter];
|
set(iter, get(iter) * other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -194,14 +202,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) * value;
|
out.set(iter, get(iter) * value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator*=(const T value) {
|
BitVec3& operator*=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) *= value;
|
set(iter, get(iter) * value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -210,14 +218,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) / other[iter];
|
out.set(iter, get(iter) / other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator/=(const BitVec3 &other) {
|
BitVec3& operator/=(const BitVec3 &other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) /= other[iter];
|
set(iter, get(iter) / other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -226,14 +234,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) / value;
|
out.set(iter, get(iter) / value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator/=(const T value) {
|
BitVec3& operator/=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) /= value;
|
set(iter, get(iter) / value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -249,7 +257,7 @@ public:
|
|||||||
|
|
||||||
BitVec3& operator>>=(const auto offset) {
|
BitVec3& operator>>=(const auto offset) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) >>= offset;
|
set(iter, get(iter) >> offset);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -258,14 +266,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) << offset;
|
out.set(iter, get(iter) << offset);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator<<=(const auto offset) {
|
BitVec3& operator<<=(const auto offset) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) <<= offset;
|
set(iter, get(iter) << offset);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -274,14 +282,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) | other[iter];
|
out.set(iter, get(iter) | other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator|=(const BitVec3 other) {
|
BitVec3& operator|=(const BitVec3 other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) |= other[iter];
|
set(iter, get(iter) | other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -290,14 +298,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) | value;
|
out.set(iter, get(iter) | value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator|=(const T value) {
|
BitVec3& operator|=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) |= value;
|
set(iter, get(iter) | value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -306,14 +314,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) & other[iter];
|
out.set(iter, get(iter) & other[iter]);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator&=(const BitVec3 other) {
|
BitVec3& operator&=(const BitVec3 other) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) &= other[iter];
|
set(iter, get(iter) & other[iter]);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -322,14 +330,14 @@ public:
|
|||||||
BitVec3 out;
|
BitVec3 out;
|
||||||
|
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
out[iter] = get(iter) & value;
|
out.set(iter, get(iter) & value);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVec3& operator&=(const T value) {
|
BitVec3& operator&=(const T value) {
|
||||||
for(size_t iter = 0; iter < N; iter++)
|
for(size_t iter = 0; iter < N; iter++)
|
||||||
get(iter) &= value;
|
set(iter, get(iter) & value);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -343,7 +351,9 @@ using bvec16i = BitVec3<int8_t, 4>;
|
|||||||
using bvec16u = BitVec3<uint8_t, 4>;
|
using bvec16u = BitVec3<uint8_t, 4>;
|
||||||
using bvec256i = BitVec3<int8_t, 8>;
|
using bvec256i = BitVec3<int8_t, 8>;
|
||||||
using bvec256u = BitVec3<uint8_t, 8>;
|
using bvec256u = BitVec3<uint8_t, 8>;
|
||||||
using bvec4096i = BitVec3<int8_t, 12>;
|
using bvec1024i = BitVec3<int16_t, 10>;
|
||||||
|
using bvec1024u = BitVec3<uint16_t, 10>;
|
||||||
|
using bvec4096i = BitVec3<int16_t, 12>;
|
||||||
using bvec4096u = BitVec3<uint16_t, 12>;
|
using bvec4096u = BitVec3<uint16_t, 12>;
|
||||||
|
|
||||||
using GlobalVoxel = BitVec3<int32_t, 24>;
|
using GlobalVoxel = BitVec3<int32_t, 24>;
|
||||||
@@ -385,11 +395,10 @@ using BinSoundId_t = ResourceId_t;
|
|||||||
using BinFontId_t = ResourceId_t;
|
using BinFontId_t = ResourceId_t;
|
||||||
|
|
||||||
// Шаблоны использования бинарных ресурсов
|
// Шаблоны использования бинарных ресурсов
|
||||||
using TextureId_t = ResourceId_t;
|
// using DefTextureId_t = ResourceId_t;
|
||||||
using AnimationId_t = ResourceId_t;
|
// using DefModelId_t = ResourceId_t;
|
||||||
using ModelId_t = ResourceId_t;
|
// using DefSoundId_t = ResourceId_t;
|
||||||
using SoundId_t = ResourceId_t;
|
// using DefFontId_t = ResourceId_t;
|
||||||
using FontId_t = ResourceId_t;
|
|
||||||
|
|
||||||
enum class EnumDefContent {
|
enum class EnumDefContent {
|
||||||
Voxel, Node, Generator, World, Portal, Entity, FuncEntitry
|
Voxel, Node, Generator, World, Portal, Entity, FuncEntitry
|
||||||
@@ -398,12 +407,11 @@ enum class EnumDefContent {
|
|||||||
// Игровые определения
|
// Игровые определения
|
||||||
using DefVoxelId_t = ResourceId_t;
|
using DefVoxelId_t = ResourceId_t;
|
||||||
using DefNodeId_t = ResourceId_t;
|
using DefNodeId_t = ResourceId_t;
|
||||||
using DefGeneratorId_t = ResourceId_t;
|
|
||||||
using DefWorldId_t = ResourceId_t;
|
using DefWorldId_t = ResourceId_t;
|
||||||
using DefPortalId_t = ResourceId_t;
|
using DefPortalId_t = ResourceId_t;
|
||||||
using DefEntityId_t = ResourceId_t;
|
using DefEntityId_t = ResourceId_t;
|
||||||
using DefFuncEntityId_t = ResourceId_t;
|
using DefFuncEntityId_t = ResourceId_t;
|
||||||
|
using DefItemId_t = ResourceId_t;
|
||||||
|
|
||||||
// Контент, основанный на игровых определениях
|
// Контент, основанный на игровых определениях
|
||||||
using WorldId_t = ResourceId_t;
|
using WorldId_t = ResourceId_t;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Common/Abstract.hpp"
|
#pragma once
|
||||||
#include <iostream>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
namespace LV {
|
namespace LV {
|
||||||
|
|
||||||
|
|||||||
@@ -138,10 +138,14 @@ enum struct L2System : uint8_t {
|
|||||||
enum struct L2Resource : uint8_t {
|
enum struct L2Resource : uint8_t {
|
||||||
Texture,
|
Texture,
|
||||||
FreeTexture,
|
FreeTexture,
|
||||||
|
Animation,
|
||||||
|
FreeAnimation,
|
||||||
Sound,
|
Sound,
|
||||||
FreeSound,
|
FreeSound,
|
||||||
Model,
|
Model,
|
||||||
FreeModel,
|
FreeModel,
|
||||||
|
Font,
|
||||||
|
FreeFont,
|
||||||
InitResSend = 253,
|
InitResSend = 253,
|
||||||
ChunkSend,
|
ChunkSend,
|
||||||
SendCanceled
|
SendCanceled
|
||||||
@@ -157,7 +161,11 @@ enum struct L2Definition : uint8_t {
|
|||||||
Portal,
|
Portal,
|
||||||
FreePortal,
|
FreePortal,
|
||||||
Entity,
|
Entity,
|
||||||
FreeEntity
|
FreeEntity,
|
||||||
|
FuncEntity,
|
||||||
|
FreeFuncEntity,
|
||||||
|
Item,
|
||||||
|
FreeItem
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct L2Content : uint8_t {
|
enum struct L2Content : uint8_t {
|
||||||
|
|||||||
@@ -4,19 +4,31 @@
|
|||||||
#include <Common/Abstract.hpp>
|
#include <Common/Abstract.hpp>
|
||||||
#include <Common/Collide.hpp>
|
#include <Common/Collide.hpp>
|
||||||
#include <boost/uuid/detail/sha1.hpp>
|
#include <boost/uuid/detail/sha1.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|
||||||
namespace LV::Server {
|
namespace LV::Server {
|
||||||
|
|
||||||
|
struct TexturePipeline {
|
||||||
|
std::vector<BinTextureId_t> BinTextures;
|
||||||
|
std::u8string Pipeline;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// В одном регионе может быть максимум 2^16 сущностей. Клиенту адресуются сущности в формате <мир>+<позиция региона>+<uint16_t>
|
// В одном регионе может быть максимум 2^16 сущностей. Клиенту адресуются сущности в формате <мир>+<позиция региона>+<uint16_t>
|
||||||
// И если сущность перешла из одного региона в другой, идентификатор сущности на стороне клиента сохраняется
|
// И если сущность перешла из одного региона в другой, идентификатор сущности на стороне клиента сохраняется
|
||||||
using EntityId_t = uint16_t;
|
using RegionEntityId_t = uint16_t;
|
||||||
using FuncEntityId_t = uint16_t;
|
using ClientEntityId_t = RegionEntityId_t;
|
||||||
using ClientEntityId_t = std::tuple<WorldId_t, Pos::GlobalRegion, EntityId_t>;
|
using ServerEntityId_t = std::tuple<WorldId_t, Pos::GlobalRegion, RegionEntityId_t>;
|
||||||
|
using RegionFuncEntityId_t = uint16_t;
|
||||||
|
using ClientFuncEntityId_t = RegionFuncEntityId_t;
|
||||||
|
using ServerFuncEntityId_t = std::tuple<WorldId_t, Pos::GlobalRegion, RegionFuncEntityId_t>;
|
||||||
|
|
||||||
using MediaStreamId_t = uint16_t;
|
using MediaStreamId_t = uint16_t;
|
||||||
using ContentBridgeId_t = ResourceId_t;
|
using ContentBridgeId_t = ResourceId_t;
|
||||||
using PlayerId_t = ResourceId_t;
|
using PlayerId_t = ResourceId_t;
|
||||||
|
using DefGeneratorId_t = ResourceId_t;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -44,25 +56,66 @@ struct ServerTime {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct VoxelCube {
|
struct VoxelCube {
|
||||||
DefVoxelId_t VoxelId;
|
union {
|
||||||
Pos::bvec256u Left, Right;
|
struct {
|
||||||
|
DefVoxelId_t VoxelId : 24, Meta : 8;
|
||||||
|
};
|
||||||
|
|
||||||
auto operator<=>(const VoxelCube&) const = default;
|
DefVoxelId_t Data = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pos::bvec256u Left, Right; // TODO: заменить на позицию и размер
|
||||||
|
|
||||||
|
auto operator<=>(const VoxelCube& other) const {
|
||||||
|
if (auto cmp = Left <=> other.Left; cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
if (auto cmp = Right <=> other.Right; cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
return Data <=> other.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const VoxelCube& other) const {
|
||||||
|
return Left == other.Left && Right == other.Right && Data == other.Data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VoxelCube_Region {
|
struct VoxelCube_Region {
|
||||||
Pos::bvec4096u Left, Right;
|
union {
|
||||||
DefVoxelId_t VoxelId;
|
struct {
|
||||||
|
DefVoxelId_t VoxelId : 24, Meta : 8;
|
||||||
|
};
|
||||||
|
|
||||||
auto operator<=>(const VoxelCube_Region&) const = default;
|
DefVoxelId_t Data = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pos::bvec1024u Left, Right; // TODO: заменить на позицию и размер
|
||||||
|
|
||||||
|
auto operator<=>(const VoxelCube_Region& other) const {
|
||||||
|
if (auto cmp = Left <=> other.Left; cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
if (auto cmp = Right <=> other.Right; cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
return Data <=> other.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const VoxelCube_Region& other) const {
|
||||||
|
return Left == other.Left && Right == other.Right && Data == other.Data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
DefNodeId_t NodeId;
|
union {
|
||||||
uint8_t Rotate : 6;
|
struct {
|
||||||
|
DefNodeId_t NodeId : 24, Meta : 8;
|
||||||
|
};
|
||||||
|
DefNodeId_t Data;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct AABB {
|
struct AABB {
|
||||||
Pos::Object VecMin, VecMax;
|
Pos::Object VecMin, VecMax;
|
||||||
|
|
||||||
@@ -96,26 +149,26 @@ struct LocalAABB {
|
|||||||
|
|
||||||
struct CollisionAABB : public AABB {
|
struct CollisionAABB : public AABB {
|
||||||
enum struct EnumType {
|
enum struct EnumType {
|
||||||
Voxel, Node, Entity, Barrier, Portal, Another
|
Voxel, Node, Entity, FuncEntity, Barrier, Portal, Another
|
||||||
} Type;
|
} Type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
EntityId_t Index;
|
RegionEntityId_t Index;
|
||||||
} Entity;
|
} Entity;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
FuncEntityId_t Index;
|
RegionFuncEntityId_t Index;
|
||||||
} FuncEntity;
|
} FuncEntity;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
Pos::bvec4u Chunk;
|
||||||
Pos::bvec16u Pos;
|
Pos::bvec16u Pos;
|
||||||
} Node;
|
} Node;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Pos::bvec16u Chunk;
|
Pos::bvec4u Chunk;
|
||||||
uint32_t Index;
|
uint32_t Index;
|
||||||
DefVoxelId_t Id;
|
|
||||||
} Voxel;
|
} Voxel;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -171,6 +224,15 @@ public:
|
|||||||
DefEntityId_t getDefId() const { return DefId; }
|
DefEntityId_t getDefId() const { return DefId; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FuncEntity {
|
||||||
|
DefFuncEntityId_t DefId;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FuncEntity(DefFuncEntityId_t defId);
|
||||||
|
|
||||||
|
DefFuncEntityId_t getDefId() const { return DefId; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename Vec>
|
template<typename Vec>
|
||||||
struct VoxelCuboidsFuncs {
|
struct VoxelCuboidsFuncs {
|
||||||
@@ -292,7 +354,7 @@ struct VoxelCuboidsFuncs {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void convertRegionVoxelsToChunks(const std::vector<VoxelCube_Region>& regions, std::vector<VoxelCube> *chunks) {
|
inline void convertRegionVoxelsToChunks(const std::vector<VoxelCube_Region>& regions, std::unordered_map<Pos::bvec4u, std::vector<VoxelCube>> &chunks) {
|
||||||
for (const auto& region : regions) {
|
for (const auto& region : regions) {
|
||||||
int minX = region.Left.x >> 8;
|
int minX = region.Left.x >> 8;
|
||||||
int minY = region.Left.y >> 8;
|
int minY = region.Left.y >> 8;
|
||||||
@@ -315,30 +377,24 @@ inline void convertRegionVoxelsToChunks(const std::vector<VoxelCube_Region>& reg
|
|||||||
static_cast<uint8_t>(std::min<uint16_t>(((z+1) << 8)-1, region.Right.z) - (z << 8))
|
static_cast<uint8_t>(std::min<uint16_t>(((z+1) << 8)-1, region.Right.z) - (z << 8))
|
||||||
};
|
};
|
||||||
|
|
||||||
int chunkIndex = z * 16 * 16 + y * 16 + x;
|
chunks[Pos::bvec4u(x, y, z)].push_back({
|
||||||
chunks[chunkIndex].emplace_back(region.VoxelId, left, right);
|
region.VoxelId, region.Meta, left, right
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void convertChunkVoxelsToRegion(const std::vector<VoxelCube> *chunks, std::vector<VoxelCube_Region> ®ions) {
|
inline void convertChunkVoxelsToRegion(const std::unordered_map<Pos::bvec4u, std::vector<VoxelCube>> &chunks, std::vector<VoxelCube_Region> ®ions) {
|
||||||
for (int x = 0; x < 16; ++x) {
|
for(const auto& [pos, voxels] : chunks) {
|
||||||
for (int y = 0; y < 16; ++y) {
|
Pos::bvec1024u left = pos << 8;
|
||||||
for (int z = 0; z < 16; ++z) {
|
for (const auto& cube : voxels) {
|
||||||
int chunkIndex = z * 16 * 16 + y * 16 + x;
|
regions.push_back({
|
||||||
|
cube.VoxelId, cube.Meta,
|
||||||
Pos::bvec4096u left(x << 8, y << 8, z << 8);
|
Pos::bvec1024u(left.x+cube.Left.x, left.y+cube.Left.y, left.z+cube.Left.z),
|
||||||
|
Pos::bvec1024u(left.x+cube.Right.x, left.y+cube.Right.y, left.z+cube.Right.z)
|
||||||
for (const auto& cube : chunks[chunkIndex]) {
|
});
|
||||||
regions.emplace_back(
|
|
||||||
Pos::bvec4096u(left.x+cube.Left.x, left.y+cube.Left.y, left.z+cube.Left.z),
|
|
||||||
Pos::bvec4096u(left.x+cube.Right.x, left.y+cube.Right.y, left.z+cube.Right.z),
|
|
||||||
cube.VoxelId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ContentEventController::ContentEventController(std::unique_ptr<RemoteClient> &&r
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ContentEventController::getViewRangeActive() const {
|
uint16_t ContentEventController::getViewRangeActive() const {
|
||||||
return 16;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ContentEventController::getViewRangeBackground() const {
|
uint16_t ContentEventController::getViewRangeBackground() const {
|
||||||
@@ -34,9 +34,9 @@ void ContentEventController::checkContentViewChanges() {
|
|||||||
for(const auto &[regionPos, chunks] : regions) {
|
for(const auto &[regionPos, chunks] : regions) {
|
||||||
size_t bitPos = chunks._Find_first();
|
size_t bitPos = chunks._Find_first();
|
||||||
while(bitPos != chunks.size()) {
|
while(bitPos != chunks.size()) {
|
||||||
Pos::Local16_u chunkPosLocal;
|
Pos::bvec4u chunkPosLocal;
|
||||||
chunkPosLocal = bitPos;
|
chunkPosLocal.unpack(bitPos);
|
||||||
Pos::GlobalChunk chunkPos = regionPos.toChunk(chunkPosLocal);
|
Pos::GlobalChunk chunkPos = (Pos::GlobalChunk(regionPos) << 2) + chunkPosLocal;
|
||||||
Remote->prepareChunkRemove(worldId, chunkPos);
|
Remote->prepareChunkRemove(worldId, chunkPos);
|
||||||
bitPos = chunks._Find_next(bitPos);
|
bitPos = chunks._Find_next(bitPos);
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ void ContentEventController::onWorldUpdate(WorldId_t worldId, World *worldObj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ContentEventController::onChunksUpdate_Voxels(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
void ContentEventController::onChunksUpdate_Voxels(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
||||||
const std::unordered_map<Pos::Local16_u, const std::vector<VoxelCube>*> &chunks)
|
const std::unordered_map<Pos::bvec4u, const std::vector<VoxelCube>*>& chunks)
|
||||||
{
|
{
|
||||||
auto pWorld = ContentViewState.find(worldId);
|
auto pWorld = ContentViewState.find(worldId);
|
||||||
if(pWorld == ContentViewState.end())
|
if(pWorld == ContentViewState.end())
|
||||||
@@ -69,19 +69,19 @@ void ContentEventController::onChunksUpdate_Voxels(WorldId_t worldId, Pos::Globa
|
|||||||
if(pRegion == pWorld->second.end())
|
if(pRegion == pWorld->second.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::bitset<4096> &chunkBitset = pRegion->second;
|
const std::bitset<64> &chunkBitset = pRegion->second;
|
||||||
|
|
||||||
for(auto pChunk : chunks) {
|
for(auto pChunk : chunks) {
|
||||||
if(!chunkBitset.test(pChunk.first))
|
if(!chunkBitset.test(pChunk.first.pack()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pos::GlobalChunk chunkPos = regionPos.toChunk(pChunk.first);
|
Pos::GlobalChunk chunkPos = (Pos::GlobalChunk(regionPos) << 2) + pChunk.first;
|
||||||
Remote->prepareChunkUpdate_Voxels(worldId, chunkPos, *pChunk.second);
|
Remote->prepareChunkUpdate_Voxels(worldId, chunkPos, pChunk.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentEventController::onChunksUpdate_Nodes(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
void ContentEventController::onChunksUpdate_Nodes(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
||||||
const std::unordered_map<Pos::Local16_u, const std::unordered_map<Pos::Local16_u, Node>*> &chunks)
|
const std::unordered_map<Pos::bvec4u, const Node*> &chunks)
|
||||||
{
|
{
|
||||||
auto pWorld = ContentViewState.find(worldId);
|
auto pWorld = ContentViewState.find(worldId);
|
||||||
if(pWorld == ContentViewState.end())
|
if(pWorld == ContentViewState.end())
|
||||||
@@ -91,41 +91,41 @@ void ContentEventController::onChunksUpdate_Nodes(WorldId_t worldId, Pos::Global
|
|||||||
if(pRegion == pWorld->second.end())
|
if(pRegion == pWorld->second.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::bitset<4096> &chunkBitset = pRegion->second;
|
const std::bitset<64> &chunkBitset = pRegion->second;
|
||||||
|
|
||||||
for(auto pChunk : chunks) {
|
for(auto pChunk : chunks) {
|
||||||
if(!chunkBitset.test(pChunk.first))
|
if(!chunkBitset.test(pChunk.first.pack()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pos::GlobalChunk chunkPos = regionPos.toChunk(pChunk.first);
|
Pos::GlobalChunk chunkPos = (Pos::GlobalChunk(regionPos) << 2) + Pos::GlobalChunk(pChunk.first);
|
||||||
Remote->prepareChunkUpdate_Nodes(worldId, chunkPos, *pChunk.second);
|
Remote->prepareChunkUpdate_Nodes(worldId, chunkPos, pChunk.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentEventController::onChunksUpdate_LightPrism(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
// void ContentEventController::onChunksUpdate_LightPrism(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
||||||
const std::unordered_map<Pos::Local16_u, const LightPrism*> &chunks)
|
// const std::unordered_map<Pos::bvec4u, const LightPrism*> &chunks)
|
||||||
{
|
// {
|
||||||
auto pWorld = ContentViewState.find(worldId);
|
// auto pWorld = ContentViewState.find(worldId);
|
||||||
if(pWorld == ContentViewState.end())
|
// if(pWorld == ContentViewState.end())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
auto pRegion = pWorld->second.find(regionPos);
|
// auto pRegion = pWorld->second.find(regionPos);
|
||||||
if(pRegion == pWorld->second.end())
|
// if(pRegion == pWorld->second.end())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
const std::bitset<4096> &chunkBitset = pRegion->second;
|
// const std::bitset<4096> &chunkBitset = pRegion->second;
|
||||||
|
|
||||||
for(auto pChunk : chunks) {
|
// for(auto pChunk : chunks) {
|
||||||
if(!chunkBitset.test(pChunk.first))
|
// if(!chunkBitset.test(pChunk.first))
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
Pos::GlobalChunk chunkPos = regionPos.toChunk(pChunk.first);
|
// Pos::GlobalChunk chunkPos = regionPos.toChunk(pChunk.first);
|
||||||
Remote->prepareChunkUpdate_LightPrism(worldId, chunkPos, pChunk.second);
|
// Remote->prepareChunkUpdate_LightPrism(worldId, chunkPos, pChunk.second);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void ContentEventController::onEntityEnterLost(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
void ContentEventController::onEntityEnterLost(WorldId_t worldId, Pos::GlobalRegion regionPos,
|
||||||
const std::unordered_set<LocalEntityId_t> &enter, const std::unordered_set<LocalEntityId_t> &lost)
|
const std::unordered_set<RegionEntityId_t> &enter, const std::unordered_set<RegionEntityId_t> &lost)
|
||||||
{
|
{
|
||||||
auto pWorld = Subscribed.Entities.find(worldId);
|
auto pWorld = Subscribed.Entities.find(worldId);
|
||||||
if(pWorld == Subscribed.Entities.end()) {
|
if(pWorld == Subscribed.Entities.end()) {
|
||||||
@@ -141,9 +141,9 @@ void ContentEventController::onEntityEnterLost(WorldId_t worldId, Pos::GlobalReg
|
|||||||
pRegion = pWorld->second.find(regionPos);
|
pRegion = pWorld->second.find(regionPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_set<LocalEntityId_t> &entityesId = pRegion->second;
|
std::unordered_set<RegionEntityId_t> &entityesId = pRegion->second;
|
||||||
|
|
||||||
for(LocalEntityId_t eId : lost) {
|
for(RegionEntityId_t eId : lost) {
|
||||||
entityesId.erase(eId);
|
entityesId.erase(eId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,13 +157,13 @@ void ContentEventController::onEntityEnterLost(WorldId_t worldId, Pos::GlobalReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Сообщить Remote
|
// Сообщить Remote
|
||||||
for(LocalEntityId_t eId : lost) {
|
for(RegionEntityId_t eId : lost) {
|
||||||
Remote->prepareEntityRemove({worldId, regionPos, eId});
|
Remote->prepareEntityRemove({worldId, regionPos, eId});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentEventController::onEntitySwap(WorldId_t lastWorldId, Pos::GlobalRegion lastRegionPos,
|
void ContentEventController::onEntitySwap(WorldId_t lastWorldId, Pos::GlobalRegion lastRegionPos,
|
||||||
LocalEntityId_t lastId, WorldId_t newWorldId, Pos::GlobalRegion newRegionPos, LocalEntityId_t newId)
|
RegionEntityId_t lastId, WorldId_t newWorldId, Pos::GlobalRegion newRegionPos, RegionEntityId_t newId)
|
||||||
{
|
{
|
||||||
// Проверим отслеживается ли эта сущность нами
|
// Проверим отслеживается ли эта сущность нами
|
||||||
auto lpWorld = Subscribed.Entities.find(lastWorldId);
|
auto lpWorld = Subscribed.Entities.find(lastWorldId);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -35,22 +34,22 @@ struct ContentViewCircle {
|
|||||||
int32_t Range;
|
int32_t Range;
|
||||||
|
|
||||||
inline int32_t sqrDistance(Pos::GlobalRegion regionPos) const {
|
inline int32_t sqrDistance(Pos::GlobalRegion regionPos) const {
|
||||||
glm::i32vec3 vec = {Pos.x-((regionPos.X << 4) | 0b1000), Pos.y-((regionPos.Y << 4) | 0b1000), Pos.z-((regionPos.Z << 4) | 0b1000)};
|
glm::i32vec3 vec = Pos-(glm::i16vec3) ((Pos::GlobalChunk(regionPos) << 2) | 0b10);
|
||||||
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int32_t sqrDistance(Pos::GlobalChunk chunkPos) const {
|
inline int32_t sqrDistance(Pos::GlobalChunk chunkPos) const {
|
||||||
glm::i32vec3 vec = {Pos.x-chunkPos.X, Pos.y-chunkPos.Y, Pos.z-chunkPos.Z};
|
glm::i32vec3 vec = Pos-(glm::i16vec3) chunkPos;
|
||||||
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int64_t sqrDistance(Pos::Object objectPos) const {
|
inline int64_t sqrDistance(Pos::Object objectPos) const {
|
||||||
glm::i32vec3 vec = {Pos.x-(objectPos.x >> 20), Pos.y-(objectPos.y >> 20), Pos.z-(objectPos.z >> 20)};
|
glm::i32vec3 vec = Pos-(glm::i16vec3) (objectPos >> 12 >> 4);
|
||||||
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
return vec.x*vec.x+vec.y*vec.y+vec.z*vec.z;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isIn(Pos::GlobalRegion regionPos) const {
|
bool isIn(Pos::GlobalRegion regionPos) const {
|
||||||
return sqrDistance(regionPos) < Range+192; // (8×sqrt(3))^2
|
return sqrDistance(regionPos) < Range+12; // (2×sqrt(3))^2
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIn(Pos::GlobalChunk chunkPos) const {
|
bool isIn(Pos::GlobalChunk chunkPos) const {
|
||||||
@@ -62,8 +61,8 @@ struct ContentViewCircle {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Регион -> чанки попавшие под обозрение Pos::Local16_u
|
// Регион -> чанки попавшие под обозрение Pos::bvec4u
|
||||||
using ContentViewWorld = std::map<Pos::GlobalRegion, std::bitset<4096>>; // 1 - чанк виден, 0 - не виден
|
using ContentViewWorld = std::map<Pos::GlobalRegion, std::bitset<64>>; // 1 - чанк виден, 0 - не виден
|
||||||
|
|
||||||
struct ContentViewGlobal_DiffInfo;
|
struct ContentViewGlobal_DiffInfo;
|
||||||
|
|
||||||
@@ -99,9 +98,9 @@ inline ContentViewGlobal_DiffInfo ContentViewGlobal::calcDiffWith(const ContentV
|
|||||||
for(const auto &[regionPos, _] : newWorldView)
|
for(const auto &[regionPos, _] : newWorldView)
|
||||||
newRegions.push_back(regionPos);
|
newRegions.push_back(regionPos);
|
||||||
} else {
|
} else {
|
||||||
const std::map<Pos::GlobalRegion, std::bitset<4096>> &newRegions = newWorldView;
|
const std::map<Pos::GlobalRegion, std::bitset<64>> &newRegions = newWorldView;
|
||||||
const std::map<Pos::GlobalRegion, std::bitset<4096>> &oldRegions = oldWorldIter->second;
|
const std::map<Pos::GlobalRegion, std::bitset<64>> &oldRegions = oldWorldIter->second;
|
||||||
std::map<Pos::GlobalRegion, std::bitset<4096>> *diffRegions = nullptr;
|
std::map<Pos::GlobalRegion, std::bitset<64>> *diffRegions = nullptr;
|
||||||
|
|
||||||
// Рассматриваем разницу меж регионами
|
// Рассматриваем разницу меж регионами
|
||||||
for(const auto &[newRegionPos, newRegionBitField] : newRegions) {
|
for(const auto &[newRegionPos, newRegionBitField] : newRegions) {
|
||||||
@@ -113,8 +112,8 @@ inline ContentViewGlobal_DiffInfo ContentViewGlobal::calcDiffWith(const ContentV
|
|||||||
(*diffRegions)[newRegionPos] = newRegionBitField;
|
(*diffRegions)[newRegionPos] = newRegionBitField;
|
||||||
newView.Regions[newWorldId].push_back(newRegionPos);
|
newView.Regions[newWorldId].push_back(newRegionPos);
|
||||||
} else {
|
} else {
|
||||||
const std::bitset<4096> &oldChunks = oldRegionIter->second;
|
const std::bitset<64> &oldChunks = oldRegionIter->second;
|
||||||
std::bitset<4096> chunks = (~oldChunks) & newRegionBitField; // Останется поле с новыми чанками
|
std::bitset<64> chunks = (~oldChunks) & newRegionBitField; // Останется поле с новыми чанками
|
||||||
if(chunks._Find_first() != chunks.size()) {
|
if(chunks._Find_first() != chunks.size()) {
|
||||||
// Есть новые чанки
|
// Есть новые чанки
|
||||||
if(!diffRegions)
|
if(!diffRegions)
|
||||||
@@ -157,7 +156,8 @@ private:
|
|||||||
struct SubscribedObj {
|
struct SubscribedObj {
|
||||||
// Используется регионами
|
// Используется регионами
|
||||||
std::vector<PortalId_t> Portals;
|
std::vector<PortalId_t> Portals;
|
||||||
std::unordered_map<WorldId_t, std::unordered_map<Pos::GlobalRegion, std::unordered_set<LocalEntityId_t>>> Entities;
|
std::unordered_map<WorldId_t, std::unordered_map<Pos::GlobalRegion, std::unordered_set<RegionEntityId_t>>> Entities;
|
||||||
|
std::unordered_map<WorldId_t, std::unordered_map<Pos::GlobalRegion, std::unordered_set<RegionEntityId_t>>> FuncEntities;
|
||||||
} Subscribed;
|
} Subscribed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -168,6 +168,8 @@ public:
|
|||||||
// Объявленная в чанках территория точно отслеживается (активная зона)
|
// Объявленная в чанках территория точно отслеживается (активная зона)
|
||||||
ContentViewGlobal ContentViewState;
|
ContentViewGlobal ContentViewState;
|
||||||
ContentViewGlobal_DiffInfo ContentView_NewView, ContentView_LostView;
|
ContentViewGlobal_DiffInfo ContentView_NewView, ContentView_LostView;
|
||||||
|
// Миры добавленные в наблюдение в текущем такте
|
||||||
|
std::vector<WorldId_t> NewWorlds;
|
||||||
|
|
||||||
// size_t CVCHash = 0; // Хэш для std::vector<ContentViewCircle>
|
// size_t CVCHash = 0; // Хэш для std::vector<ContentViewCircle>
|
||||||
// std::unordered_map<WorldId_t, std::vector<Pos::GlobalRegion>> SubscribedRegions;
|
// std::unordered_map<WorldId_t, std::vector<Pos::GlobalRegion>> SubscribedRegions;
|
||||||
@@ -190,14 +192,18 @@ public:
|
|||||||
void onWorldUpdate(WorldId_t worldId, World *worldObj);
|
void onWorldUpdate(WorldId_t worldId, World *worldObj);
|
||||||
|
|
||||||
// Нужно фильтровать неотслеживаемые чанки
|
// Нужно фильтровать неотслеживаемые чанки
|
||||||
void onChunksUpdate_Voxels(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::Local16_u, const std::vector<VoxelCube>*> &chunks);
|
void onChunksUpdate_Voxels(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::bvec4u, const std::vector<VoxelCube>*> &chunks);
|
||||||
void onChunksUpdate_Nodes(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::Local16_u, const std::unordered_map<Pos::Local16_u, Node>*> &chunks);
|
void onChunksUpdate_Nodes(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::bvec4u, const Node*> &chunks);
|
||||||
void onChunksUpdate_LightPrism(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::Local16_u, const LightPrism*> &chunks);
|
//void onChunksUpdate_LightPrism(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_map<Pos::bvec4u, const LightPrism*> &chunks);
|
||||||
|
|
||||||
void onEntityEnterLost(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_set<LocalEntityId_t> &enter, const std::unordered_set<LocalEntityId_t> &lost);
|
void onEntityEnterLost(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_set<RegionEntityId_t> &enter, const std::unordered_set<RegionEntityId_t> &lost);
|
||||||
void onEntitySwap(WorldId_t lastWorldId, Pos::GlobalRegion lastRegionPos, LocalEntityId_t lastId, WorldId_t newWorldId, Pos::GlobalRegion newRegionPos, LocalEntityId_t newId);
|
void onEntitySwap(WorldId_t lastWorldId, Pos::GlobalRegion lastRegionPos, RegionEntityId_t lastId, WorldId_t newWorldId, Pos::GlobalRegion newRegionPos, RegionEntityId_t newId);
|
||||||
void onEntityUpdates(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::vector<Entity> &entities);
|
void onEntityUpdates(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::vector<Entity> &entities);
|
||||||
|
|
||||||
|
void onFuncEntityEnterLost(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::unordered_set<RegionEntityId_t> &enter, const std::unordered_set<RegionEntityId_t> &lost);
|
||||||
|
void onFuncEntitySwap(WorldId_t lastWorldId, Pos::GlobalRegion lastRegionPos, RegionEntityId_t lastId, WorldId_t newWorldId, Pos::GlobalRegion newRegionPos, RegionEntityId_t newId);
|
||||||
|
void onFuncEntityUpdates(WorldId_t worldId, Pos::GlobalRegion regionPos, const std::vector<Entity> &entities);
|
||||||
|
|
||||||
void onPortalEnterLost(const std::vector<void*> &enter, const std::vector<void*> &lost);
|
void onPortalEnterLost(const std::vector<void*> &enter, const std::vector<void*> &lost);
|
||||||
void onPortalUpdates(const std::vector<void*> &portals);
|
void onPortalUpdates(const std::vector<void*> &portals);
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void GameServer::Expanse_t::_accumulateContentViewCircles(ContentViewCircle circ
|
|||||||
ContentViewGlobal GameServer::Expanse_t::makeContentViewGlobal(const std::vector<ContentViewCircle> &views) {
|
ContentViewGlobal GameServer::Expanse_t::makeContentViewGlobal(const std::vector<ContentViewCircle> &views) {
|
||||||
ContentViewGlobal cvg;
|
ContentViewGlobal cvg;
|
||||||
Pos::GlobalRegion posRegion, lastPosRegion;
|
Pos::GlobalRegion posRegion, lastPosRegion;
|
||||||
std::bitset<4096> *cache = nullptr;
|
std::bitset<64> *cache = nullptr;
|
||||||
|
|
||||||
for(const ContentViewCircle &circle : views) {
|
for(const ContentViewCircle &circle : views) {
|
||||||
ContentViewWorld &cvw = cvg[circle.WorldId];
|
ContentViewWorld &cvw = cvg[circle.WorldId];
|
||||||
@@ -123,14 +123,14 @@ ContentViewGlobal GameServer::Expanse_t::makeContentViewGlobal(const std::vector
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pos::GlobalChunk posChunk(x+circle.Pos.x, y+circle.Pos.y, z+circle.Pos.z);
|
Pos::GlobalChunk posChunk(x+circle.Pos.x, y+circle.Pos.y, z+circle.Pos.z);
|
||||||
posRegion.fromChunk(posChunk);
|
posRegion = posChunk >> 2;
|
||||||
|
|
||||||
if(!cache || lastPosRegion != posRegion) {
|
if(!cache || lastPosRegion != posRegion) {
|
||||||
lastPosRegion = posRegion;
|
lastPosRegion = posRegion;
|
||||||
cache = &cvw[posRegion];
|
cache = &cvw[posRegion];
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->_Unchecked_set(posChunk.toLocal());
|
cache->_Unchecked_set(Pos::bvec4u(posChunk).pack());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,17 +279,19 @@ Region* GameServer::forceGetRegion(WorldId_t worldId, Pos::GlobalRegion pos) {
|
|||||||
region->IsLoaded = true;
|
region->IsLoaded = true;
|
||||||
region->load(&data);
|
region->load(&data);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
region->IsLoaded = true;
|
region->IsLoaded = true;
|
||||||
if(pos.Y == 0) {
|
if(pos.y == 0) {
|
||||||
for(int z = 0; z < 16; z++)
|
for(int z = 0; z < 4; z++)
|
||||||
for(int x = 0; x < 16; x++) {
|
for(int y = 0; y < 4; y++)
|
||||||
region->Voxels[x][0][z].push_back({0, {0, 0, 0}, {255, 255, 255},});
|
for(int x = 0; x < 4; x++) {
|
||||||
|
Node *nodes = (Node*) ®ion->Nodes[0][0][0][z][y][x];
|
||||||
|
for(int index = 0; index < 16*16*16; index++)
|
||||||
|
nodes[index] = {static_cast<DefNodeId_t>(y == 0 ? 1 : 0), 0};
|
||||||
|
region->IsChunkChanged_Nodes |= (y == 0 ? 1 : 0) << (z*4*4+y*4+x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fill(region->IsChunkChanged_Voxels, region->IsChunkChanged_Voxels+64, ~0);
|
|
||||||
return region.get();
|
return region.get();
|
||||||
} else {
|
} else {
|
||||||
return iterRegion->second.get();
|
return iterRegion->second.get();
|
||||||
@@ -403,27 +405,43 @@ void GameServer::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameServer::stepContent() {
|
void GameServer::stepContent() {
|
||||||
Content.TextureM.update(CurrentTickDuration);
|
Content.Texture.update(CurrentTickDuration);
|
||||||
if(Content.TextureM.hasPreparedInformation()) {
|
if(Content.Texture.hasPreparedInformation()) {
|
||||||
auto table = Content.TextureM.takePreparedInformation();
|
auto table = Content.Texture.takePreparedInformation();
|
||||||
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
||||||
cec->Remote->informateDefTexture(table);
|
cec->Remote->informateBinTexture(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Content.ModelM.update(CurrentTickDuration);
|
Content.Animation.update(CurrentTickDuration);
|
||||||
if(Content.ModelM.hasPreparedInformation()) {
|
if(Content.Animation.hasPreparedInformation()) {
|
||||||
auto table = Content.ModelM.takePreparedInformation();
|
auto table = Content.Animation.takePreparedInformation();
|
||||||
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
||||||
cec->Remote->informateDefTexture(table);
|
cec->Remote->informateBinAnimation(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Content.SoundM.update(CurrentTickDuration);
|
Content.Model.update(CurrentTickDuration);
|
||||||
if(Content.SoundM.hasPreparedInformation()) {
|
if(Content.Model.hasPreparedInformation()) {
|
||||||
auto table = Content.SoundM.takePreparedInformation();
|
auto table = Content.Model.takePreparedInformation();
|
||||||
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
||||||
cec->Remote->informateDefTexture(table);
|
cec->Remote->informateBinModel(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Content.Sound.update(CurrentTickDuration);
|
||||||
|
if(Content.Sound.hasPreparedInformation()) {
|
||||||
|
auto table = Content.Sound.takePreparedInformation();
|
||||||
|
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
||||||
|
cec->Remote->informateBinSound(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Content.Font.update(CurrentTickDuration);
|
||||||
|
if(Content.Font.hasPreparedInformation()) {
|
||||||
|
auto table = Content.Font.takePreparedInformation();
|
||||||
|
for(std::unique_ptr<ContentEventController> &cec : Game.CECs) {
|
||||||
|
cec->Remote->informateBinFont(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,6 +520,17 @@ void GameServer::stepWorlds() {
|
|||||||
for(auto &pair : Expanse.Worlds)
|
for(auto &pair : Expanse.Worlds)
|
||||||
pair.second->onUpdate(this, CurrentTickDuration);
|
pair.second->onUpdate(this, CurrentTickDuration);
|
||||||
|
|
||||||
|
// Оповещаем о новых мирах
|
||||||
|
for(const std::unique_ptr<ContentEventController>& cec : Game.CECs) {
|
||||||
|
for(WorldId_t id : cec->NewWorlds) {
|
||||||
|
auto iter = Expanse.Worlds.find(id);
|
||||||
|
assert(iter != Expanse.Worlds.end());
|
||||||
|
cec->onWorldUpdate(id, iter->second.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
cec->NewWorlds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
for(auto &pWorld : Expanse.Worlds) {
|
for(auto &pWorld : Expanse.Worlds) {
|
||||||
World &wobj = *pWorld.second;
|
World &wobj = *pWorld.second;
|
||||||
|
|
||||||
@@ -675,10 +704,10 @@ void GameServer::stepWorlds() {
|
|||||||
if(rPos != pRegion.first || pWorld.first != entity.WorldId) {
|
if(rPos != pRegion.first || pWorld.first != entity.WorldId) {
|
||||||
|
|
||||||
Region *toRegion = forceGetRegion(entity.WorldId, rPos);
|
Region *toRegion = forceGetRegion(entity.WorldId, rPos);
|
||||||
LocalEntityId_t newId = toRegion->pushEntity(entity);
|
RegionEntityId_t newId = toRegion->pushEntity(entity);
|
||||||
// toRegion->Entityes[newId].WorldId = Если мир изменился
|
// toRegion->Entityes[newId].WorldId = Если мир изменился
|
||||||
|
|
||||||
if(newId == LocalEntityId_t(-1)) {
|
if(newId == RegionEntityId_t(-1)) {
|
||||||
// В другом регионе нет места
|
// В другом регионе нет места
|
||||||
} else {
|
} else {
|
||||||
entity.IsRemoved = true;
|
entity.IsRemoved = true;
|
||||||
@@ -692,45 +721,42 @@ void GameServer::stepWorlds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Проверить необходимость перерасчёта вертикальной проходимости света
|
// Проверить необходимость перерасчёта вертикальной проходимости света
|
||||||
std::unordered_map<Pos::Local16_u, const LightPrism*> ChangedLightPrism;
|
// std::unordered_map<Pos::bvec4u, const LightPrism*> ChangedLightPrism;
|
||||||
{
|
// {
|
||||||
for(int big = 0; big < 64; big++) {
|
// for(int big = 0; big < 64; big++) {
|
||||||
uint64_t bits = region.IsChunkChanged_Voxels[big] | region.IsChunkChanged_Nodes[big];
|
// uint64_t bits = region.IsChunkChanged_Voxels[big] | region.IsChunkChanged_Nodes[big];
|
||||||
|
|
||||||
if(!bits)
|
// if(!bits)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
for(int little = 0; little < 64; little++) {
|
// for(int little = 0; little < 64; little++) {
|
||||||
if(((bits >> little) & 1) == 0)
|
// if(((bits >> little) & 1) == 0)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Сбор данных об изменившихся чанках
|
// Сбор данных об изменившихся чанках
|
||||||
std::unordered_map<Pos::Local16_u, const std::vector<VoxelCube>*> ChangedVoxels;
|
std::unordered_map<Pos::bvec4u, const std::vector<VoxelCube>*> ChangedVoxels;
|
||||||
std::unordered_map<Pos::Local16_u, const std::unordered_map<Pos::Local16_u, Node>*> ChangedNodes;
|
std::unordered_map<Pos::bvec4u, const Node*> ChangedNodes;
|
||||||
{
|
{
|
||||||
|
if(!region.IsChunkChanged_Voxels && !region.IsChunkChanged_Nodes)
|
||||||
for(int big = 0; big < 64; big++) {
|
|
||||||
uint64_t bits_voxels = region.IsChunkChanged_Voxels[big];
|
|
||||||
uint64_t bits_nodes = region.IsChunkChanged_Nodes[big];
|
|
||||||
|
|
||||||
if(!bits_voxels && !bits_nodes)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(int little = 0; little < 64; little++) {
|
for(int index = 0; index < 64; index++) {
|
||||||
Pos::Local16_u pos(little & 0xf, ((big & 0x3) << 2) | (little >> 4), big >> 2);
|
Pos::bvec4u pos;
|
||||||
|
pos.unpack(index);
|
||||||
|
|
||||||
if(((bits_voxels >> little) & 1) == 1) {
|
if(((region.IsChunkChanged_Voxels >> index) & 1) == 1) {
|
||||||
ChangedVoxels[pos] = ®ion.Voxels[pos.X][pos.Y][pos.Z];
|
auto iter = region.Voxels.find(pos);
|
||||||
|
assert(iter != region.Voxels.end());
|
||||||
|
ChangedVoxels[pos] = &iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((bits_nodes >> little) & 1) == 1) {
|
if(((region.IsChunkChanged_Nodes >> index) & 1) == 1) {
|
||||||
ChangedNodes[pos] = ®ion.Nodes[pos.X][pos.Y][pos.Z];
|
ChangedNodes[pos] = (Node*) ®ion.Nodes[0][0][0][pos.x][pos.y][pos.z];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,11 +788,11 @@ void GameServer::stepWorlds() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Наблюдаемые чанки
|
// Наблюдаемые чанки
|
||||||
const std::bitset<4096> &chunkBitset = chunkBitsetIter->second;
|
const std::bitset<64> &chunkBitset = chunkBitsetIter->second;
|
||||||
|
|
||||||
// Пересылка изменений в регионе
|
// Пересылка изменений в регионе
|
||||||
if(!ChangedLightPrism.empty())
|
// if(!ChangedLightPrism.empty())
|
||||||
cec->onChunksUpdate_LightPrism(pWorld.first, pRegion.first, ChangedLightPrism);
|
// cec->onChunksUpdate_LightPrism(pWorld.first, pRegion.first, ChangedLightPrism);
|
||||||
|
|
||||||
if(!ChangedVoxels.empty())
|
if(!ChangedVoxels.empty())
|
||||||
cec->onChunksUpdate_Voxels(pWorld.first, pRegion.first, ChangedVoxels);
|
cec->onChunksUpdate_Voxels(pWorld.first, pRegion.first, ChangedVoxels);
|
||||||
@@ -776,31 +802,31 @@ void GameServer::stepWorlds() {
|
|||||||
|
|
||||||
// Отправка полной информации о новых наблюдаемых чанках
|
// Отправка полной информации о новых наблюдаемых чанках
|
||||||
{
|
{
|
||||||
const std::bitset<4096> *new_chunkBitset = nullptr;
|
const std::bitset<64> *new_chunkBitset = nullptr;
|
||||||
try { new_chunkBitset = &cec->ContentView_NewView.View.at(pWorld.first).at(pRegion.first); } catch(...) {}
|
try { new_chunkBitset = &cec->ContentView_NewView.View.at(pWorld.first).at(pRegion.first); } catch(...) {}
|
||||||
|
|
||||||
if(new_chunkBitset) {
|
if(new_chunkBitset) {
|
||||||
std::unordered_map<Pos::Local16_u, const LightPrism*> newLightPrism;
|
//std::unordered_map<Pos::bvec4u, const LightPrism*> newLightPrism;
|
||||||
std::unordered_map<Pos::Local16_u, const std::vector<VoxelCube>*> newVoxels;
|
std::unordered_map<Pos::bvec4u, const std::vector<VoxelCube>*> newVoxels;
|
||||||
std::unordered_map<Pos::Local16_u, const std::unordered_map<Pos::Local16_u, Node>*> newNodes;
|
std::unordered_map<Pos::bvec4u, const Node*> newNodes;
|
||||||
|
|
||||||
newLightPrism.reserve(new_chunkBitset->count());
|
//newLightPrism.reserve(new_chunkBitset->count());
|
||||||
newVoxels.reserve(new_chunkBitset->count());
|
newVoxels.reserve(new_chunkBitset->count());
|
||||||
newNodes.reserve(new_chunkBitset->count());
|
newNodes.reserve(new_chunkBitset->count());
|
||||||
|
|
||||||
size_t bitPos = new_chunkBitset->_Find_first();
|
size_t bitPos = new_chunkBitset->_Find_first();
|
||||||
while(bitPos != new_chunkBitset->size()) {
|
while(bitPos != new_chunkBitset->size()) {
|
||||||
Pos::Local16_u chunkPos;
|
Pos::bvec4u chunkPos;
|
||||||
chunkPos = bitPos;
|
chunkPos = bitPos;
|
||||||
|
|
||||||
newLightPrism.insert({chunkPos, ®ion.Lights[0][0][chunkPos.X][chunkPos.Y][chunkPos.Z]});
|
//newLightPrism.insert({chunkPos, ®ion.Lights[0][0][chunkPos.X][chunkPos.Y][chunkPos.Z]});
|
||||||
newVoxels.insert({chunkPos, ®ion.Voxels[chunkPos.X][chunkPos.Y][chunkPos.Z]});
|
newVoxels.insert({chunkPos, ®ion.Voxels[chunkPos]});
|
||||||
newNodes.insert({chunkPos, ®ion.Nodes[chunkPos.X][chunkPos.Y][chunkPos.Z]});
|
newNodes.insert({chunkPos, ®ion.Nodes[0][0][0][chunkPos.x][chunkPos.y][chunkPos.z]});
|
||||||
|
|
||||||
bitPos = new_chunkBitset->_Find_next(bitPos);
|
bitPos = new_chunkBitset->_Find_next(bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
cec->onChunksUpdate_LightPrism(pWorld.first, pRegion.first, newLightPrism);
|
//cec->onChunksUpdate_LightPrism(pWorld.first, pRegion.first, newLightPrism);
|
||||||
cec->onChunksUpdate_Voxels(pWorld.first, pRegion.first, newVoxels);
|
cec->onChunksUpdate_Voxels(pWorld.first, pRegion.first, newVoxels);
|
||||||
cec->onChunksUpdate_Nodes(pWorld.first, pRegion.first, newNodes);
|
cec->onChunksUpdate_Nodes(pWorld.first, pRegion.first, newNodes);
|
||||||
}
|
}
|
||||||
@@ -894,7 +920,7 @@ void GameServer::stepWorlds() {
|
|||||||
region.IsChanged = false;
|
region.IsChanged = false;
|
||||||
|
|
||||||
SB_Region data;
|
SB_Region data;
|
||||||
convertChunkVoxelsToRegion((const std::vector<VoxelCube>*) region.Voxels, data.Voxels);
|
convertChunkVoxelsToRegion(region.Voxels, data.Voxels);
|
||||||
SaveBackend.World->save(worldStringId, pRegion.first, &data);
|
SaveBackend.World->save(worldStringId, pRegion.first, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,9 +930,8 @@ void GameServer::stepWorlds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Сброс информации об изменившихся данных
|
// Сброс информации об изменившихся данных
|
||||||
|
region.IsChunkChanged_Voxels = 0;
|
||||||
std::fill(region.IsChunkChanged_Voxels, region.IsChunkChanged_Voxels+64, 0);
|
region.IsChunkChanged_Nodes = 0;
|
||||||
std::fill(region.IsChunkChanged_Nodes, region.IsChunkChanged_Nodes+64, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Pos::GlobalRegion regionPos : regionsToRemove) {
|
for(Pos::GlobalRegion regionPos : regionsToRemove) {
|
||||||
@@ -931,7 +956,7 @@ void GameServer::stepWorlds() {
|
|||||||
|
|
||||||
// TODO: Передефайнить идентификаторы нод
|
// TODO: Передефайнить идентификаторы нод
|
||||||
|
|
||||||
convertRegionVoxelsToChunks(data.Voxels, (std::vector<VoxelCube>*) robj.Voxels);
|
convertRegionVoxelsToChunks(data.Voxels, robj.Voxels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -980,6 +1005,22 @@ void GameServer::stepViewContent() {
|
|||||||
ContentViewGlobal_DiffInfo lostView = cec.ContentViewState.calcDiffWith(newCbg);
|
ContentViewGlobal_DiffInfo lostView = cec.ContentViewState.calcDiffWith(newCbg);
|
||||||
if(!newView.empty() || !lostView.empty()) {
|
if(!newView.empty() || !lostView.empty()) {
|
||||||
lost_CVG.insert({&cec, {newView}});
|
lost_CVG.insert({&cec, {newView}});
|
||||||
|
|
||||||
|
std::vector<WorldId_t> newWorlds, lostWorlds;
|
||||||
|
|
||||||
|
// Поиск потерянных миров
|
||||||
|
for(const auto& [key, _] : cec.ContentViewState) {
|
||||||
|
if(!newCbg.contains(key))
|
||||||
|
lostWorlds.push_back(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Поиск новых увиденных миров
|
||||||
|
for(const auto& [key, _] : newCbg) {
|
||||||
|
if(!cec.ContentViewState.contains(key))
|
||||||
|
newWorlds.push_back(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
cec.NewWorlds = std::move(newWorlds);
|
||||||
cec.ContentViewState = std::move(newCbg);
|
cec.ContentViewState = std::move(newCbg);
|
||||||
cec.ContentView_NewView = std::move(newView);
|
cec.ContentView_NewView = std::move(newView);
|
||||||
cec.ContentView_LostView = std::move(lostView);
|
cec.ContentView_LostView = std::move(lostView);
|
||||||
@@ -1011,15 +1052,20 @@ void GameServer::stepSendPlayersPackets() {
|
|||||||
|
|
||||||
full.uniq();
|
full.uniq();
|
||||||
|
|
||||||
if(!full.NewTextures.empty())
|
if(!full.BinTexture.empty())
|
||||||
Content.TextureM.needResourceResponse(full.NewTextures);
|
Content.Texture.needResourceResponse(full.BinTexture);
|
||||||
|
|
||||||
if(!full.NewModels.empty())
|
if(!full.BinAnimation.empty())
|
||||||
Content.ModelM.needResourceResponse(full.NewModels);
|
Content.Animation.needResourceResponse(full.BinAnimation);
|
||||||
|
|
||||||
if(!full.NewSounds.empty())
|
if(!full.BinModel.empty())
|
||||||
Content.SoundM.needResourceResponse(full.NewSounds);
|
Content.Model.needResourceResponse(full.BinModel);
|
||||||
|
|
||||||
|
if(!full.BinSound.empty())
|
||||||
|
Content.Sound.needResourceResponse(full.BinSound);
|
||||||
|
|
||||||
|
if(!full.BinFont.empty())
|
||||||
|
Content.Font.needResourceResponse(full.BinFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameServer::stepLoadRegions() {
|
void GameServer::stepLoadRegions() {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "World.hpp"
|
#include "World.hpp"
|
||||||
|
|
||||||
#include "SaveBackend.hpp"
|
#include "SaveBackend.hpp"
|
||||||
#include "boost/asio/ip/address.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace LV::Server {
|
namespace LV::Server {
|
||||||
@@ -51,20 +50,24 @@ class GameServer : public AsyncObject {
|
|||||||
// WorldDefManager WorldDM;
|
// WorldDefManager WorldDM;
|
||||||
// VoxelDefManager VoxelDM;
|
// VoxelDefManager VoxelDM;
|
||||||
// NodeDefManager NodeDM;
|
// NodeDefManager NodeDM;
|
||||||
BinaryResourceManager TextureM;
|
BinaryResourceManager Texture;
|
||||||
BinaryResourceManager ModelM;
|
BinaryResourceManager Animation;
|
||||||
BinaryResourceManager SoundM;
|
BinaryResourceManager Model;
|
||||||
|
BinaryResourceManager Sound;
|
||||||
|
BinaryResourceManager Font;
|
||||||
|
|
||||||
ContentObj(asio::io_context &ioc,
|
ContentObj(asio::io_context &ioc,
|
||||||
std::shared_ptr<ResourceFile> zeroTexture,
|
std::shared_ptr<ResourceFile> zeroTexture,
|
||||||
|
std::shared_ptr<ResourceFile> zeroAnimation,
|
||||||
std::shared_ptr<ResourceFile> zeroModel,
|
std::shared_ptr<ResourceFile> zeroModel,
|
||||||
std::shared_ptr<ResourceFile> zeroSound)
|
std::shared_ptr<ResourceFile> zeroSound,
|
||||||
: TextureM(ioc, zeroTexture),
|
std::shared_ptr<ResourceFile> zeroFont)
|
||||||
ModelM(ioc, zeroModel),
|
: Texture(ioc, zeroTexture),
|
||||||
SoundM(ioc, zeroSound)
|
Animation(ioc, zeroAnimation),
|
||||||
{
|
Model(ioc, zeroModel),
|
||||||
|
Sound(ioc, zeroSound),
|
||||||
}
|
Font(ioc, zeroFont)
|
||||||
|
{}
|
||||||
|
|
||||||
} Content;
|
} Content;
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ class GameServer : public AsyncObject {
|
|||||||
public:
|
public:
|
||||||
GameServer(asio::io_context &ioc, fs::path worldPath)
|
GameServer(asio::io_context &ioc, fs::path worldPath)
|
||||||
: AsyncObject(ioc),
|
: AsyncObject(ioc),
|
||||||
Content(ioc, nullptr, nullptr, nullptr)
|
Content(ioc, nullptr, nullptr, nullptr, nullptr, nullptr)
|
||||||
{
|
{
|
||||||
init(worldPath);
|
init(worldPath);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -138,30 +138,43 @@ public:
|
|||||||
этих ресурсов и переотправлять их клиенту
|
этих ресурсов и переотправлять их клиенту
|
||||||
*/
|
*/
|
||||||
struct ResourceRequest {
|
struct ResourceRequest {
|
||||||
std::vector<BinTextureId_t> NewTextures;
|
std::vector<BinTextureId_t> BinTexture;
|
||||||
std::vector<BinModelId_t> NewModels;
|
std::vector<BinAnimationId_t> BinAnimation;
|
||||||
std::vector<BinSoundId_t> NewSounds;
|
std::vector<BinModelId_t> BinModel;
|
||||||
|
std::vector<BinSoundId_t> BinSound;
|
||||||
|
std::vector<BinFontId_t> BinFont;
|
||||||
|
|
||||||
std::vector<DefWorldId_t> NewWorlds;
|
std::vector<DefVoxelId_t> Voxel;
|
||||||
std::vector<DefVoxelId_t> NewVoxels;
|
std::vector<DefNodeId_t> Node;
|
||||||
std::vector<DefNodeId_t> NewNodes;
|
std::vector<DefWorldId_t> World;
|
||||||
std::vector<DefPortalId_t> NewPortals;
|
std::vector<DefPortalId_t> Portal;
|
||||||
std::vector<DefEntityId_t> NewEntityes;
|
std::vector<DefEntityId_t> Entity;
|
||||||
|
std::vector<DefFuncEntityId_t> FuncEntity;
|
||||||
|
std::vector<DefItemId_t> Item;
|
||||||
|
|
||||||
void insert(const ResourceRequest &obj) {
|
void insert(const ResourceRequest &obj) {
|
||||||
NewTextures.insert(NewTextures.end(), obj.NewTextures.begin(), obj.NewTextures.end());
|
BinTexture.insert(BinTexture.end(), obj.BinTexture.begin(), obj.BinTexture.end());
|
||||||
NewModels.insert(NewModels.end(), obj.NewModels.begin(), obj.NewModels.end());
|
BinAnimation.insert(BinAnimation.end(), obj.BinAnimation.begin(), obj.BinAnimation.end());
|
||||||
NewSounds.insert(NewSounds.end(), obj.NewSounds.begin(), obj.NewSounds.end());
|
BinModel.insert(BinModel.end(), obj.BinModel.begin(), obj.BinModel.end());
|
||||||
|
BinSound.insert(BinSound.end(), obj.BinSound.begin(), obj.BinSound.end());
|
||||||
|
BinFont.insert(BinFont.end(), obj.BinFont.begin(), obj.BinFont.end());
|
||||||
|
|
||||||
NewWorlds.insert(NewWorlds.end(), obj.NewWorlds.begin(), obj.NewWorlds.end());
|
Voxel.insert(Voxel.end(), obj.Voxel.begin(), obj.Voxel.end());
|
||||||
NewVoxels.insert(NewVoxels.end(), obj.NewVoxels.begin(), obj.NewVoxels.end());
|
Node.insert(Node.end(), obj.Node.begin(), obj.Node.end());
|
||||||
NewNodes.insert(NewNodes.end(), obj.NewNodes.begin(), obj.NewNodes.end());
|
World.insert(World.end(), obj.World.begin(), obj.World.end());
|
||||||
NewPortals.insert(NewPortals.end(), obj.NewPortals.begin(), obj.NewPortals.end());
|
Portal.insert(Portal.end(), obj.Portal.begin(), obj.Portal.end());
|
||||||
NewEntityes.insert(NewEntityes.end(), obj.NewEntityes.begin(), obj.NewEntityes.end());
|
Entity.insert(Entity.end(), obj.Entity.begin(), obj.Entity.end());
|
||||||
|
FuncEntity.insert(FuncEntity.end(), obj.FuncEntity.begin(), obj.FuncEntity.end());
|
||||||
|
Item.insert(Item.end(), obj.Item.begin(), obj.Item.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void uniq() {
|
void uniq() {
|
||||||
for(std::vector<ResourceId_t> *vec : {&NewTextures, &NewModels, &NewSounds, &NewWorlds, &NewVoxels, &NewNodes, &NewPortals, &NewEntityes}) {
|
for(std::vector<ResourceId_t> *vec : {
|
||||||
|
&BinTexture, &BinAnimation, &BinModel, &BinSound,
|
||||||
|
&BinFont, &Voxel, &Node, &World,
|
||||||
|
&Portal, &Entity, &FuncEntity, &Item
|
||||||
|
})
|
||||||
|
{
|
||||||
std::sort(vec->begin(), vec->end());
|
std::sort(vec->begin(), vec->end());
|
||||||
auto last = std::unique(vec->begin(), vec->end());
|
auto last = std::unique(vec->begin(), vec->end());
|
||||||
vec->erase(last, vec->end());
|
vec->erase(last, vec->end());
|
||||||
@@ -169,7 +182,7 @@ struct ResourceRequest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using EntityKey = std::tuple<WorldId_c, Pos::GlobalRegion>;
|
// using EntityKey = std::tuple<WorldId_c, Pos::GlobalRegion>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -186,85 +199,109 @@ class RemoteClient {
|
|||||||
DestroyLock UseLock;
|
DestroyLock UseLock;
|
||||||
Net::AsyncSocket Socket;
|
Net::AsyncSocket Socket;
|
||||||
bool IsConnected = true, IsGoingShutdown = false;
|
bool IsConnected = true, IsGoingShutdown = false;
|
||||||
std::vector<HASH> ClientCache;
|
std::vector<HASH> ClientBinaryCache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
При обнаружении нового контента составляется запрос (ResourceRequest)
|
||||||
|
на полное описание ресурса. Это описание отправляется клиенту и используется
|
||||||
|
чтобы выстроить зависимость какие базовые ресурсы использует контент.
|
||||||
|
Если базовые ресурсы не известны, то они также запрашиваются.
|
||||||
|
*/
|
||||||
|
|
||||||
struct ResUsesObj {
|
struct ResUsesObj {
|
||||||
// Счётчики использования базовых ресурсов высшими объектами
|
// Счётчики использования двоичных кэшируемых ресурсов
|
||||||
std::map<BinTextureId_t, uint32_t> BinTexture;
|
std::map<BinTextureId_t, uint32_t> BinTexture;
|
||||||
std::map<BinSoundId_t, uint32_t> BinSound;
|
std::map<BinAnimationId_t, uint32_t> BinAnimation;
|
||||||
|
|
||||||
// Может использовать текстуры
|
|
||||||
std::map<BinModelId_t, uint32_t> BinModel;
|
std::map<BinModelId_t, uint32_t> BinModel;
|
||||||
|
std::map<BinSoundId_t, uint32_t> BinSound;
|
||||||
|
std::map<BinFontId_t, uint32_t> BinFont;
|
||||||
|
|
||||||
// Будут использовать в своих определениях текстуры, звуки, модели
|
// Счётчики использование профилей контента
|
||||||
std::map<DefWorldId_t, uint32_t> DefWorld;
|
std::map<DefVoxelId_t, uint32_t> DefVoxel; // Один чанк, одно использование
|
||||||
std::map<DefVoxelId_t, uint32_t> DefVoxel;
|
|
||||||
std::map<DefNodeId_t, uint32_t> DefNode;
|
std::map<DefNodeId_t, uint32_t> DefNode;
|
||||||
|
std::map<DefWorldId_t, uint32_t> DefWorld;
|
||||||
std::map<DefPortalId_t, uint32_t> DefPortal;
|
std::map<DefPortalId_t, uint32_t> DefPortal;
|
||||||
std::map<DefEntityId_t, uint32_t> DefEntity;
|
std::map<DefEntityId_t, uint32_t> DefEntity;
|
||||||
|
std::map<DefFuncEntityId_t, uint32_t> DefFuncEntity;
|
||||||
|
std::map<DefItemId_t, uint32_t> DefItem; // При передаче инвентарей?
|
||||||
|
|
||||||
|
// Зависимость профилей контента от профилей ресурсов
|
||||||
// Переписываемый контент
|
// Нужно чтобы пересчитать зависимости к профилям ресурсов
|
||||||
|
struct RefDefVoxel_t {
|
||||||
// Сущности используют текстуры, звуки, модели
|
std::vector<BinTextureId_t> Texture;
|
||||||
struct EntityResourceUse {
|
std::vector<BinSoundId_t> Sound;
|
||||||
DefEntityId_t DefId;
|
|
||||||
|
|
||||||
std::unordered_set<BinTextureId_t> Textures;
|
|
||||||
std::unordered_set<BinSoundId_t> Sounds;
|
|
||||||
std::unordered_set<BinModelId_t> Models;
|
|
||||||
};
|
};
|
||||||
|
std::map<DefVoxelId_t, RefDefVoxel_t> RefDefVoxel;
|
||||||
std::map<GlobalEntityId_t, EntityResourceUse> Entity;
|
struct RefDefNode_t {
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
// Чанки используют воксели, ноды
|
std::vector<BinSoundId_t> Sound;
|
||||||
std::map<std::tuple<WorldId_t, Pos::GlobalChunk>, std::unordered_set<DefVoxelId_t>> ChunkVoxels;
|
|
||||||
std::map<std::tuple<WorldId_t, Pos::GlobalChunk>, std::unordered_set<DefNodeId_t>> ChunkNodes;
|
|
||||||
|
|
||||||
// Миры
|
|
||||||
struct WorldResourceUse {
|
|
||||||
DefWorldId_t DefId;
|
|
||||||
|
|
||||||
std::unordered_set<BinTextureId_t> Textures;
|
|
||||||
std::unordered_set<BinSoundId_t> Sounds;
|
|
||||||
std::unordered_set<BinModelId_t> Models;
|
|
||||||
};
|
};
|
||||||
|
std::map<DefNodeId_t, RefDefNode_t> RefDefNode;
|
||||||
std::map<WorldId_t, WorldResourceUse> Worlds;
|
struct RefDefWorld_t {
|
||||||
|
std::vector<BinTextureId_t> Texture;
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
// Порталы
|
|
||||||
struct PortalResourceUse {
|
|
||||||
DefPortalId_t DefId;
|
|
||||||
|
|
||||||
std::unordered_set<BinTextureId_t> Textures;
|
|
||||||
std::unordered_set<BinSoundId_t> Sounds;
|
|
||||||
std::unordered_set<BinModelId_t> Models;
|
|
||||||
};
|
};
|
||||||
|
std::map<WorldId_t, RefDefWorld_t> RefDefWorld;
|
||||||
|
struct RefDefPortal_t {
|
||||||
|
std::vector<BinTextureId_t> Texture;
|
||||||
|
std::vector<BinAnimationId_t> Animation;
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
|
};
|
||||||
|
std::map<DefPortalId_t, RefDefPortal_t> RefDefPortal;
|
||||||
|
struct RefDefEntity_t {
|
||||||
|
std::vector<BinTextureId_t> Texture;
|
||||||
|
std::vector<BinAnimationId_t> Animation;
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
|
};
|
||||||
|
std::map<DefEntityId_t, RefDefEntity_t> RefDefEntity;
|
||||||
|
struct RefDefFuncEntity_t {
|
||||||
|
std::vector<BinTextureId_t> Texture;
|
||||||
|
std::vector<BinAnimationId_t> Animation;
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
|
};
|
||||||
|
std::map<DefFuncEntityId_t, RefDefFuncEntity_t> RefDefFuncEntity;
|
||||||
|
struct RefDefItem_t {
|
||||||
|
std::vector<BinTextureId_t> Texture;
|
||||||
|
std::vector<BinAnimationId_t> Animation;
|
||||||
|
std::vector<BinModelId_t> Model;
|
||||||
|
};
|
||||||
|
std::map<DefItemId_t, RefDefItem_t> RefDefItem;
|
||||||
|
|
||||||
std::map<PortalId_t, PortalResourceUse> Portals;
|
// Модификационные зависимости экземпляров профилей контента
|
||||||
|
struct ChunkRef {
|
||||||
|
// Отсортированные списки уникальных вокселей
|
||||||
|
std::vector<DefVoxelId_t> Voxel;
|
||||||
|
std::vector<DefNodeId_t> Node;
|
||||||
|
};
|
||||||
|
std::map<WorldId_t, std::map<Pos::GlobalChunk, ChunkRef>> RefChunk;
|
||||||
|
struct RefWorld_t {
|
||||||
|
DefWorldId_t Profile;
|
||||||
|
};
|
||||||
|
std::map<WorldId_t, RefWorld_t> RefWorld;
|
||||||
|
struct RefPortal_t {
|
||||||
|
DefPortalId_t Profile;
|
||||||
|
};
|
||||||
|
std::map<PortalId_t, RefPortal_t> RefPortal;
|
||||||
|
struct RefEntity_t {
|
||||||
|
DefEntityId_t Profile;
|
||||||
|
};
|
||||||
|
std::map<ServerEntityId_t, RefEntity_t> RefEntity;
|
||||||
|
struct RefFuncEntity_t {
|
||||||
|
DefFuncEntityId_t Profile;
|
||||||
|
};
|
||||||
|
std::map<ServerFuncEntityId_t, RefFuncEntity_t> RefFuncEntity;
|
||||||
|
|
||||||
} ResUses;
|
} ResUses;
|
||||||
|
|
||||||
|
// Смена идентификаторов сервера на клиентские
|
||||||
struct {
|
struct {
|
||||||
SCSKeyRemapper<BinTextureId_t, TextureId_c> BinTextures;
|
SCSKeyRemapper<ServerEntityId_t, ClientEntityId_t> Entityes;
|
||||||
SCSKeyRemapper<BinSoundId_t, SoundId_c> BinSounds;
|
SCSKeyRemapper<ServerFuncEntityId_t, ClientEntityId_t> FuncEntityes;
|
||||||
SCSKeyRemapper<BinModelId_t, ModelId_c> BinModels;
|
|
||||||
|
|
||||||
SCSKeyRemapper<DefWorldId_t, DefWorldId_c> DefWorlds;
|
|
||||||
SCSKeyRemapper<DefVoxelId_t, DefVoxelId_c> DefVoxels;
|
|
||||||
SCSKeyRemapper<DefNodeId_t, DefNodeId_c> DefNodes;
|
|
||||||
SCSKeyRemapper<DefPortalId_t, DefPortalId_c> DefPortals;
|
|
||||||
SCSKeyRemapper<DefEntityId_t, DefEntityId_c> DefEntityes;
|
|
||||||
|
|
||||||
SCSKeyRemapper<WorldId_t, WorldId_c> Worlds;
|
|
||||||
SCSKeyRemapper<PortalId_t, PortalId_c> Portals;
|
|
||||||
SCSKeyRemapper<GlobalEntityId_t, EntityId_c> Entityes;
|
|
||||||
} ResRemap;
|
} ResRemap;
|
||||||
|
|
||||||
Net::Packet NextPacket;
|
Net::Packet NextPacket;
|
||||||
ResourceRequest NextRequest;
|
|
||||||
std::vector<Net::Packet> SimplePackets;
|
std::vector<Net::Packet> SimplePackets;
|
||||||
|
ResourceRequest NextRequest;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const std::string Username;
|
const std::string Username;
|
||||||
@@ -273,7 +310,7 @@ public:
|
|||||||
|
|
||||||
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)
|
||||||
: LOG("RemoteClient " + username), Socket(ioc, std::move(socket)), Username(username), ClientCache(std::move(client_cache))
|
: LOG("RemoteClient " + username), Socket(ioc, std::move(socket)), Username(username), ClientBinaryCache(std::move(client_cache))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,27 +328,40 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Функции подготавливают пакеты к отправке
|
// Функции подготавливают пакеты к отправке
|
||||||
|
|
||||||
// Отслеживаемое игроком использование контента
|
// Отслеживаемое игроком использование контента
|
||||||
// Maybe?
|
// В зоне видимости добавился чанк или изменились его воксели
|
||||||
// Текущий список вокселей, определения нод, которые больше не используются в чанке, и определения нод, которые теперь используются
|
void prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::vector<VoxelCube>* voxels);
|
||||||
//void prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::vector<VoxelCube> &voxels, const std::vector<DefVoxelId_t> &noLongerInUseDefs, const std::vector<DefVoxelId_t> &nowUsed);
|
// В зоне видимости добавился чанк или изменились его ноды
|
||||||
void prepareChunkUpdate_Voxels(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::vector<VoxelCube> &voxels);
|
void prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const Node* nodes);
|
||||||
void prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::unordered_map<Pos::Local16_u, Node> &nodes);
|
void prepareChunkUpdate_Nodes(WorldId_t worldId, Pos::GlobalChunk chunkPos, const std::unordered_map<Pos::bvec16u, Node> &nodes);
|
||||||
void prepareChunkUpdate_LightPrism(WorldId_t worldId, Pos::GlobalChunk chunkPos, const LightPrism *lights);
|
//void prepareChunkUpdate_LightPrism(WorldId_t worldId, Pos::GlobalChunk chunkPos, const LightPrism *lights);
|
||||||
|
// Чанк удалён из зоны видимости
|
||||||
void prepareChunkRemove(WorldId_t worldId, Pos::GlobalChunk chunkPos);
|
void prepareChunkRemove(WorldId_t worldId, Pos::GlobalChunk chunkPos);
|
||||||
|
|
||||||
void prepareEntitySwap(GlobalEntityId_t prevEntityId, GlobalEntityId_t nextEntityId);
|
// В зоне видимости добавилась новая сущность или она изменилась
|
||||||
void prepareEntityUpdate(GlobalEntityId_t entityId, const Entity *entity);
|
void prepareEntityUpdate(ServerEntityId_t entityId, const Entity *entity);
|
||||||
void prepareEntityRemove(GlobalEntityId_t entityId);
|
// Наблюдаемая сущность пересекла границы региона, у неё изменился серверный идентификатор
|
||||||
|
void prepareEntitySwap(ServerEntityId_t prevEntityId, ServerEntityId_t nextEntityId);
|
||||||
|
// Клиент перестал наблюдать за сущностью
|
||||||
|
void prepareEntityRemove(ServerEntityId_t entityId);
|
||||||
|
|
||||||
|
void prepareFuncEntitySwap(ServerEntityId_t prevEntityId, ServerEntityId_t nextEntityId);
|
||||||
|
void prepareFuncEntityUpdate(ServerEntityId_t entityId, const FuncEntity *funcRntity);
|
||||||
|
void prepareFuncEntityRemove(ServerEntityId_t entityId);
|
||||||
|
|
||||||
|
// В зоне видимости добавился мир или он изменился
|
||||||
void prepareWorldUpdate(WorldId_t worldId, World* world);
|
void prepareWorldUpdate(WorldId_t worldId, World* world);
|
||||||
|
// Клиент перестал наблюдать за миром
|
||||||
void prepareWorldRemove(WorldId_t worldId);
|
void prepareWorldRemove(WorldId_t worldId);
|
||||||
|
|
||||||
|
// В зоне видимости добавился порта или он изменился
|
||||||
void preparePortalUpdate(PortalId_t portalId, void* portal);
|
void preparePortalUpdate(PortalId_t portalId, void* portal);
|
||||||
|
// Клиент перестал наблюдать за порталом
|
||||||
void preparePortalRemove(PortalId_t portalId);
|
void preparePortalRemove(PortalId_t portalId);
|
||||||
|
|
||||||
// Прочие моменты
|
// Прочие моменты
|
||||||
void prepareCameraSetEntity(GlobalEntityId_t entityId);
|
void prepareCameraSetEntity(ServerEntityId_t entityId);
|
||||||
|
|
||||||
// Отправка подготовленных пакетов
|
// Отправка подготовленных пакетов
|
||||||
ResourceRequest pushPreparedPackets();
|
ResourceRequest pushPreparedPackets();
|
||||||
@@ -321,16 +371,20 @@ public:
|
|||||||
// Глобально их можно запросить в выдаче pushPreparedPackets()
|
// Глобально их можно запросить в выдаче pushPreparedPackets()
|
||||||
|
|
||||||
// Двоичные файлы
|
// Двоичные файлы
|
||||||
void informateDefTexture(const std::unordered_map<BinTextureId_t, std::shared_ptr<ResourceFile>> &textures);
|
void informateBinTexture(const std::unordered_map<BinTextureId_t, std::shared_ptr<ResourceFile>> &textures);
|
||||||
void informateDefSound(const std::unordered_map<BinSoundId_t, std::shared_ptr<ResourceFile>> &sounds);
|
void informateBinAnimation(const std::unordered_map<BinAnimationId_t, std::shared_ptr<ResourceFile>> &animations);
|
||||||
void informateDefModel(const std::unordered_map<BinModelId_t, std::shared_ptr<ResourceFile>> &models);
|
void informateBinModel(const std::unordered_map<BinModelId_t, std::shared_ptr<ResourceFile>> &models);
|
||||||
|
void informateBinSound(const std::unordered_map<BinSoundId_t, std::shared_ptr<ResourceFile>> &sounds);
|
||||||
|
void informateBinFont(const std::unordered_map<BinFontId_t, std::shared_ptr<ResourceFile>> &fonts);
|
||||||
|
|
||||||
// Игровые определения
|
// Игровые определения
|
||||||
void informateDefWorld(const std::unordered_map<DefWorldId_t, World*> &worlds);
|
|
||||||
void informateDefVoxel(const std::unordered_map<DefVoxelId_t, void*> &voxels);
|
void informateDefVoxel(const std::unordered_map<DefVoxelId_t, void*> &voxels);
|
||||||
void informateDefNode(const std::unordered_map<DefNodeId_t, void*> &nodes);
|
void informateDefNode(const std::unordered_map<DefNodeId_t, void*> &nodes);
|
||||||
void informateDefEntityes(const std::unordered_map<DefEntityId_t, void*> &entityes);
|
void informateDefWorld(const std::unordered_map<DefWorldId_t, void*> &worlds);
|
||||||
void informateDefPortals(const std::unordered_map<DefPortalId_t, void*> &portals);
|
void informateDefPortal(const std::unordered_map<DefPortalId_t, void*> &portals);
|
||||||
|
void informateDefEntity(const std::unordered_map<DefEntityId_t, void*> &entityes);
|
||||||
|
void informateDefFuncEntity(const std::unordered_map<DefFuncEntityId_t, void*> &funcEntityes);
|
||||||
|
void informateDefItem(const std::unordered_map<DefItemId_t, void*> &items);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkPacketBorder(uint16_t size);
|
void checkPacketBorder(uint16_t size);
|
||||||
@@ -338,10 +392,24 @@ private:
|
|||||||
coro<> readPacket(Net::AsyncSocket &sock);
|
coro<> readPacket(Net::AsyncSocket &sock);
|
||||||
coro<> rP_System(Net::AsyncSocket &sock);
|
coro<> rP_System(Net::AsyncSocket &sock);
|
||||||
|
|
||||||
void incrementBinary(std::unordered_set<BinTextureId_t> &textures, std::unordered_set<BinSoundId_t> &sounds,
|
void incrementBinary(const std::vector<BinTextureId_t> &textures, const std::vector<BinAnimationId_t> &animation,
|
||||||
std::unordered_set<BinModelId_t> &models);
|
const std::vector<BinSoundId_t> &sounds, const std::vector<BinModelId_t> &models,
|
||||||
void decrementBinary(std::unordered_set<BinTextureId_t> &textures, std::unordered_set<BinSoundId_t> &sounds,
|
const std::vector<BinFontId_t> &fonts
|
||||||
std::unordered_set<BinModelId_t> &models);
|
);
|
||||||
|
void decrementBinary(std::vector<BinTextureId_t>&& textures, std::vector<BinAnimationId_t>&& animation,
|
||||||
|
std::vector<BinSoundId_t>&& sounds, std::vector<BinModelId_t>&& models,
|
||||||
|
std::vector<BinFontId_t>&& fonts
|
||||||
|
);
|
||||||
|
void informateBin(ToClient::L2Resource type, ResourceId_t id, const std::shared_ptr<ResourceFile>& pair);
|
||||||
|
|
||||||
|
// void incrementProfile(const std::vector<TextureId_t> &textures, const std::vector<ModelId_t> &model,
|
||||||
|
// const std::vector<SoundId_t> &sounds, const std::vector<FontId_t> &font
|
||||||
|
// );
|
||||||
|
// void decrementProfile(std::vector<TextureId_t> &&textures, std::vector<ModelId_t> &&model,
|
||||||
|
// std::vector<SoundId_t> &&sounds, std::vector<FontId_t> &&font
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace LV::Server {
|
|||||||
struct SB_Region {
|
struct SB_Region {
|
||||||
std::vector<VoxelCube_Region> Voxels;
|
std::vector<VoxelCube_Region> Voxels;
|
||||||
std::unordered_map<DefVoxelId_t, std::string> VoxelsMap;
|
std::unordered_map<DefVoxelId_t, std::string> VoxelsMap;
|
||||||
std::unordered_map<Pos::Local16_u, Node> Nodes;
|
std::unordered_map<Pos::bvec16u, Node> Nodes;
|
||||||
std::unordered_map<DefNodeId_t, std::string> NodeMap;
|
std::unordered_map<DefNodeId_t, std::string> NodeMap;
|
||||||
std::vector<Entity> Entityes;
|
std::vector<Entity> Entityes;
|
||||||
std::unordered_map<DefEntityId_t, std::string> EntityMap;
|
std::unordered_map<DefEntityId_t, std::string> EntityMap;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs::path getPath(std::string worldId, Pos::GlobalRegion regionPos) {
|
fs::path getPath(std::string worldId, Pos::GlobalRegion regionPos) {
|
||||||
return Dir / worldId / std::to_string(regionPos.X) / std::to_string(regionPos.Y) / std::to_string(regionPos.Z);
|
return Dir / worldId / std::to_string(regionPos.x) / std::to_string(regionPos.y) / std::to_string(regionPos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isAsync() { return false; };
|
virtual bool isAsync() { return false; };
|
||||||
@@ -48,13 +48,13 @@ public:
|
|||||||
for(js::value &jvVoxel : jaVoxels) {
|
for(js::value &jvVoxel : jaVoxels) {
|
||||||
js::object &joVoxel = jvVoxel.as_object();
|
js::object &joVoxel = jvVoxel.as_object();
|
||||||
VoxelCube_Region cube;
|
VoxelCube_Region cube;
|
||||||
cube.VoxelId = joVoxel.at("Material").as_uint64();
|
cube.Data = joVoxel.at("Data").as_uint64();
|
||||||
cube.Left.X = joVoxel.at("LeftX").as_uint64();
|
cube.Left.x = joVoxel.at("LeftX").as_uint64();
|
||||||
cube.Left.Y = joVoxel.at("LeftY").as_uint64();
|
cube.Left.y = joVoxel.at("LeftY").as_uint64();
|
||||||
cube.Left.Z = joVoxel.at("LeftZ").as_uint64();
|
cube.Left.z = joVoxel.at("LeftZ").as_uint64();
|
||||||
cube.Right.X = joVoxel.at("RightX").as_uint64();
|
cube.Right.x = joVoxel.at("RightX").as_uint64();
|
||||||
cube.Right.Y = joVoxel.at("RightY").as_uint64();
|
cube.Right.y = joVoxel.at("RightY").as_uint64();
|
||||||
cube.Right.Z = joVoxel.at("RightZ").as_uint64();
|
cube.Right.z = joVoxel.at("RightZ").as_uint64();
|
||||||
data->Voxels.push_back(cube);
|
data->Voxels.push_back(cube);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,13 +74,13 @@ public:
|
|||||||
js::array jaVoxels;
|
js::array jaVoxels;
|
||||||
for(const VoxelCube_Region &cube : data->Voxels) {
|
for(const VoxelCube_Region &cube : data->Voxels) {
|
||||||
js::object joVoxel;
|
js::object joVoxel;
|
||||||
joVoxel["Material"] = cube.VoxelId;
|
joVoxel["Data"] = cube.Data;
|
||||||
joVoxel["LeftX"] = cube.Left.X;
|
joVoxel["LeftX"] = cube.Left.x;
|
||||||
joVoxel["LeftY"] = cube.Left.Y;
|
joVoxel["LeftY"] = cube.Left.y;
|
||||||
joVoxel["LeftZ"] = cube.Left.Z;
|
joVoxel["LeftZ"] = cube.Left.z;
|
||||||
joVoxel["RightX"] = cube.Right.X;
|
joVoxel["RightX"] = cube.Right.x;
|
||||||
joVoxel["RightY"] = cube.Right.Y;
|
joVoxel["RightY"] = cube.Right.y;
|
||||||
joVoxel["RightZ"] = cube.Right.Z;
|
joVoxel["RightZ"] = cube.Right.z;
|
||||||
jaVoxels.push_back(std::move(joVoxel));
|
jaVoxels.push_back(std::move(joVoxel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,16 +15,17 @@ class GameServer;
|
|||||||
|
|
||||||
class Region {
|
class Region {
|
||||||
public:
|
public:
|
||||||
uint64_t IsChunkChanged_Voxels[64] = {0};
|
uint64_t IsChunkChanged_Voxels = 0;
|
||||||
uint64_t IsChunkChanged_Nodes[64] = {0};
|
uint64_t IsChunkChanged_Nodes = 0;
|
||||||
bool IsChanged = false; // Изменён ли был регион, относительно последнего сохранения
|
bool IsChanged = false; // Изменён ли был регион, относительно последнего сохранения
|
||||||
// cx cy cz
|
std::unordered_map<Pos::bvec4u, std::vector<VoxelCube>> Voxels;
|
||||||
std::vector<VoxelCube> Voxels[16][16][16];
|
|
||||||
// x y cx cy cz
|
// x y cx cy cz
|
||||||
LightPrism Lights[16][16][16][16][16];
|
//LightPrism Lights[16][16][4][4][4];
|
||||||
std::unordered_map<Pos::Local16_u, Node> Nodes[16][16][16];
|
|
||||||
|
Node Nodes[16][16][16][4][4][4];
|
||||||
|
|
||||||
std::vector<Entity> Entityes;
|
std::vector<Entity> Entityes;
|
||||||
|
std::vector<FuncEntity> FuncEntityes;
|
||||||
std::vector<ContentEventController*> CECs;
|
std::vector<ContentEventController*> CECs;
|
||||||
// Используется для прорежения количества проверок на наблюдаемые чанки и сущности
|
// Используется для прорежения количества проверок на наблюдаемые чанки и сущности
|
||||||
// В одно обновление региона - проверка одного наблюдателя
|
// В одно обновление региона - проверка одного наблюдателя
|
||||||
@@ -35,11 +36,10 @@ public:
|
|||||||
|
|
||||||
void getCollideBoxes(Pos::GlobalRegion rPos, AABB aabb, std::vector<CollisionAABB> &boxes) {
|
void getCollideBoxes(Pos::GlobalRegion rPos, AABB aabb, std::vector<CollisionAABB> &boxes) {
|
||||||
// Абсолютная позиция начала региона
|
// Абсолютная позиция начала региона
|
||||||
Pos::Object raPos(rPos.X, rPos.Y, rPos.Z);
|
Pos::Object raPos = Pos::Object(rPos) << Pos::Object_t::BS_Bit;
|
||||||
raPos <<= Pos::Object_t::BS_Bit;
|
|
||||||
|
|
||||||
// Бокс региона
|
// Бокс региона
|
||||||
AABB regionAABB(raPos, raPos+Pos::Object(Pos::Object_t::BS*256));
|
AABB regionAABB(raPos, raPos+Pos::Object(Pos::Object_t::BS*64));
|
||||||
|
|
||||||
// Если регион не загружен, то он весь непроходим
|
// Если регион не загружен, то он весь непроходим
|
||||||
if(!IsLoaded) {
|
if(!IsLoaded) {
|
||||||
@@ -65,46 +65,48 @@ public:
|
|||||||
|
|
||||||
// Собираем коробки вокселей
|
// Собираем коробки вокселей
|
||||||
if(aabb.isCollideWith(regionAABB)) {
|
if(aabb.isCollideWith(regionAABB)) {
|
||||||
|
// Определяем с какими чанками есть пересечения
|
||||||
glm::ivec3 beg, end;
|
glm::ivec3 beg, end;
|
||||||
for(int axis = 0; axis < 3; axis++)
|
for(int axis = 0; axis < 3; axis++)
|
||||||
beg[axis] = std::max(aabb.VecMin[axis], regionAABB.VecMin[axis]) >> 16;
|
beg[axis] = std::max(aabb.VecMin[axis], regionAABB.VecMin[axis]) >> 12 >> 4;
|
||||||
for(int axis = 0; axis < 3; axis++)
|
for(int axis = 0; axis < 3; axis++)
|
||||||
end[axis] = (std::min(aabb.VecMax[axis], regionAABB.VecMax[axis])+0xffff) >> 16;
|
end[axis] = (std::min(aabb.VecMax[axis], regionAABB.VecMax[axis])+0xffff) >> 12 >> 4;
|
||||||
|
|
||||||
for(; beg.z <= end.z; beg.z++)
|
for(; beg.z <= end.z; beg.z++)
|
||||||
for(; beg.y <= end.y; beg.y++)
|
for(; beg.y <= end.y; beg.y++)
|
||||||
for(; beg.x <= end.x; beg.x++) {
|
for(; beg.x <= end.x; beg.x++) {
|
||||||
std::vector<VoxelCube> &voxels = Voxels[beg.x][beg.y][beg.z];
|
auto iterVoxels = Voxels.find(Pos::bvec4u(beg));
|
||||||
|
|
||||||
if(voxels.empty())
|
if(iterVoxels == Voxels.end() && iterVoxels->second.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto &voxels = iterVoxels->second;
|
||||||
|
|
||||||
CollisionAABB aabbInfo = CollisionAABB(regionAABB);
|
CollisionAABB aabbInfo = CollisionAABB(regionAABB);
|
||||||
for(int axis = 0; axis < 3; axis++)
|
for(int axis = 0; axis < 3; axis++)
|
||||||
aabbInfo.VecMin[axis] |= beg[axis] << 16;
|
aabbInfo.VecMin.set(axis, aabbInfo.VecMin[axis] | beg[axis] << 16);
|
||||||
|
|
||||||
for(size_t iter = 0; iter < voxels.size(); iter++) {
|
for(size_t iter = 0; iter < voxels.size(); iter++) {
|
||||||
VoxelCube &cube = voxels[iter];
|
VoxelCube &cube = voxels[iter];
|
||||||
|
|
||||||
for(int axis = 0; axis < 3; axis++)
|
for(int axis = 0; axis < 3; axis++)
|
||||||
aabbInfo.VecMin[axis] &= ~0xff00;
|
aabbInfo.VecMin.set(axis, aabbInfo.VecMin[axis] & ~0xff00);
|
||||||
aabbInfo.VecMax = aabbInfo.VecMin;
|
aabbInfo.VecMax = aabbInfo.VecMin;
|
||||||
|
|
||||||
aabbInfo.VecMin.x |= int(cube.Left.X) << 8;
|
aabbInfo.VecMin.x |= int(cube.Left.x) << 8;
|
||||||
aabbInfo.VecMin.y |= int(cube.Left.Y) << 8;
|
aabbInfo.VecMin.y |= int(cube.Left.y) << 8;
|
||||||
aabbInfo.VecMin.z |= int(cube.Left.Z) << 8;
|
aabbInfo.VecMin.z |= int(cube.Left.z) << 8;
|
||||||
|
|
||||||
aabbInfo.VecMax.x |= int(cube.Right.X) << 8;
|
aabbInfo.VecMax.x |= int(cube.Right.x) << 8;
|
||||||
aabbInfo.VecMax.y |= int(cube.Right.Y) << 8;
|
aabbInfo.VecMax.y |= int(cube.Right.y) << 8;
|
||||||
aabbInfo.VecMax.z |= int(cube.Right.Z) << 8;
|
aabbInfo.VecMax.z |= int(cube.Right.z) << 8;
|
||||||
|
|
||||||
if(aabb.isCollideWith(aabbInfo)) {
|
if(aabb.isCollideWith(aabbInfo)) {
|
||||||
aabbInfo = {
|
aabbInfo = {
|
||||||
.Type = CollisionAABB::EnumType::Voxel,
|
.Type = CollisionAABB::EnumType::Voxel,
|
||||||
.Voxel = {
|
.Voxel = {
|
||||||
.Chunk = Pos::Local16_u(beg.x, beg.y, beg.z),
|
.Chunk = Pos::bvec4u(beg.x, beg.y, beg.z),
|
||||||
.Index = static_cast<uint32_t>(iter),
|
.Index = static_cast<uint32_t>(iter),
|
||||||
.Id = cube.VoxelId
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,7 +120,7 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalEntityId_t pushEntity(Entity &entity) {
|
RegionEntityId_t pushEntity(Entity &entity) {
|
||||||
for(size_t iter = 0; iter < Entityes.size(); iter++) {
|
for(size_t iter = 0; iter < Entityes.size(); iter++) {
|
||||||
Entity &obj = Entityes[iter];
|
Entity &obj = Entityes[iter];
|
||||||
|
|
||||||
@@ -135,16 +137,17 @@ public:
|
|||||||
return Entityes.size()-1;
|
return Entityes.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LocalEntityId_t(-1);
|
// В регионе не осталось места
|
||||||
|
return RegionEntityId_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(SB_Region *data) {
|
void load(SB_Region *data) {
|
||||||
convertRegionVoxelsToChunks(data->Voxels, (std::vector<VoxelCube>*) Voxels);
|
convertRegionVoxelsToChunks(data->Voxels, Voxels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(SB_Region *data) {
|
void save(SB_Region *data) {
|
||||||
data->Voxels.clear();
|
data->Voxels.clear();
|
||||||
convertChunkVoxelsToRegion((const std::vector<VoxelCube>*) Voxels, data->Voxels);
|
convertChunkVoxelsToRegion(Voxels, data->Voxels);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user