Реформа ресурсов
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
|
||||
namespace LV::Client {
|
||||
|
||||
using EntityId_t = uint16_t;
|
||||
using FuncEntityId_t = uint16_t;
|
||||
|
||||
struct GlobalTime {
|
||||
uint32_t Seconds : 22 = 0, Sub : 10 = 0;
|
||||
|
||||
@@ -31,12 +34,12 @@ struct GlobalTime {
|
||||
};
|
||||
|
||||
struct VoxelCube {
|
||||
DefVoxelId_c VoxelId;
|
||||
Pos::Local256_u Left, Size;
|
||||
DefVoxelId_t VoxelId;
|
||||
Pos::bvec256u Left, Size;
|
||||
};
|
||||
|
||||
struct Node {
|
||||
DefNodeId_c NodeId;
|
||||
DefNodeId_t NodeId;
|
||||
uint8_t Rotate : 6;
|
||||
};
|
||||
|
||||
@@ -46,16 +49,16 @@ struct Chunk {
|
||||
// Кубы вокселей в чанке
|
||||
std::vector<VoxelCube> Voxels;
|
||||
// Ноды
|
||||
std::unordered_map<Pos::Local16_u, Node> Nodes;
|
||||
std::unordered_map<Pos::bvec16u, Node> Nodes;
|
||||
// Ограничения прохождения света, идущего от солнца (от верха карты до верхней плоскости чанка)
|
||||
LightPrism Lights[16][16];
|
||||
// LightPrism Lights[16][16];
|
||||
};
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
// PosQuat
|
||||
DefWorldId_c WorldId;
|
||||
DefPortalId_c LastUsedPortal;
|
||||
WorldId_t WorldId;
|
||||
PortalId_t LastUsedPortal;
|
||||
Pos::Object Pos;
|
||||
glm::quat Quat;
|
||||
static constexpr uint16_t HP_BS = 4096, HP_BS_Bit = 12;
|
||||
@@ -70,10 +73,17 @@ public:
|
||||
/* Интерфейс рендера текущего подключения к серверу */
|
||||
class IRenderSession {
|
||||
public:
|
||||
virtual void onDefTexture(TextureId_c id, std::vector<std::byte> &&info) = 0;
|
||||
virtual void onDefTextureLost(const std::vector<TextureId_c> &&lost) = 0;
|
||||
virtual void onDefModel(ModelId_c id, std::vector<std::byte> &&info) = 0;
|
||||
virtual void onDefModelLost(const std::vector<ModelId_c> &&lost) = 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 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;
|
||||
|
||||
@@ -2,170 +2,416 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <glm/ext.hpp>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace LV {
|
||||
namespace Pos {
|
||||
|
||||
struct Local4_u {
|
||||
uint8_t X : 2, Y : 2, Z : 2;
|
||||
template<typename T, size_t BitsPerComponent>
|
||||
class BitVec3 {
|
||||
static_assert(std::is_integral_v<T>, "T must be an integral type");
|
||||
static_assert(BitsPerComponent > 0, "Bits per component must be at least 1");
|
||||
static constexpr size_t N = 3;
|
||||
|
||||
using Key = uint8_t;
|
||||
operator Key() const {
|
||||
return Key(X) | (Key(Y) << 2) | (Key(Z) << 4);
|
||||
};
|
||||
};
|
||||
static constexpr auto getType() {
|
||||
constexpr size_t bits = N*BitsPerComponent;
|
||||
if constexpr(bits <= 8)
|
||||
return uint8_t(0);
|
||||
else if constexpr(bits <= 16)
|
||||
return uint16_t(0);
|
||||
else if constexpr(bits <= 32)
|
||||
return uint32_t(0);
|
||||
else if constexpr(bits <= 64)
|
||||
return uint64_t(0);
|
||||
else {
|
||||
static_assert("Нет подходящего хранилища");
|
||||
return uint8_t(0);
|
||||
}
|
||||
}
|
||||
public:
|
||||
using Pack = decltype(getType());
|
||||
using Type = T;
|
||||
using value_type = Type;
|
||||
|
||||
struct Local16_u {
|
||||
uint8_t X : 4, Y : 4, Z : 4;
|
||||
T x : BitsPerComponent, y : BitsPerComponent, z : BitsPerComponent;
|
||||
|
||||
using Key = uint16_t;
|
||||
operator Key() const {
|
||||
return Key(X) | (Key(Y) << 4) | (Key(Z) << 8);
|
||||
};
|
||||
public:
|
||||
BitVec3() = default;
|
||||
BitVec3(T value)
|
||||
: x(value), y(value), z(value)
|
||||
{
|
||||
}
|
||||
BitVec3(const T x, const T y, const T z)
|
||||
: x(x), y(y), z(z)
|
||||
{}
|
||||
BitVec3(const BitVec3&) = default;
|
||||
BitVec3(BitVec3&&) = default;
|
||||
|
||||
BitVec3& operator=(const BitVec3&) = default;
|
||||
BitVec3& operator=(BitVec3&&) = default;
|
||||
|
||||
void set(size_t index, const T value) {
|
||||
assert(index < N);
|
||||
if(index == 0)
|
||||
x = value;
|
||||
else if(index == 1)
|
||||
y = value;
|
||||
else if(index == 2)
|
||||
z = value;
|
||||
}
|
||||
|
||||
const T get(size_t index) const {
|
||||
assert(index < N);
|
||||
if(index == 0)
|
||||
return x;
|
||||
else if(index == 1)
|
||||
return y;
|
||||
else if(index == 2)
|
||||
return z;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const T operator[](size_t index) const {
|
||||
return get(index);
|
||||
}
|
||||
|
||||
Pack pack() const requires (N*BitsPerComponent <= 64) {
|
||||
Pack out = 0;
|
||||
using U = std::make_unsigned_t<T>;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++) {
|
||||
out |= Pack(U(get(iter))) << BitsPerComponent*iter;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void unpack(const Pack pack) requires (N*BitsPerComponent <= 64) {
|
||||
using U = std::make_unsigned_t<T>;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++) {
|
||||
get(iter) = U((pack >> BitsPerComponent*iter) & ((Pack(1) << BitsPerComponent)-1));
|
||||
}
|
||||
}
|
||||
|
||||
auto operator<=>(const BitVec3&) const = default;
|
||||
|
||||
template<typename T2, size_t BitsPerComponent2>
|
||||
operator BitVec3<T2, BitsPerComponent2>() const {
|
||||
BitVec3<T, BitsPerComponent2> out;
|
||||
for(size_t iter = 0; iter < N; iter++) {
|
||||
out.set(iter, T2(std::make_unsigned_t<T2>(std::make_unsigned_t<T>(get(iter)))));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3 operator+(const BitVec3 &other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) + other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator+=(const BitVec3 &other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) += other[iter];
|
||||
|
||||
Local16_u& operator=(const Key &key) {
|
||||
X = key & 0xf;
|
||||
Y = (key >> 4) & 0xf;
|
||||
Z = (key >> 8) & 0xf;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Local4_u left() const { return Local4_u{uint8_t(uint16_t(X) >> 2), uint8_t(uint16_t(Y) >> 2), uint8_t(uint16_t(Z) >> 2)}; }
|
||||
Local4_u right() const { return Local4_u{uint8_t(uint16_t(X) & 0b11), uint8_t(uint16_t(Y) & 0b11), uint8_t(uint16_t(Z) & 0b11)}; }
|
||||
};
|
||||
BitVec3 operator+(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
struct Local16 {
|
||||
int8_t X : 4, Y : 4, Z : 4;
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) + value;
|
||||
|
||||
using Key = uint16_t;
|
||||
operator Key() const {
|
||||
return Key(uint8_t(X)) | (Key(uint8_t(Y) << 4)) | (Key(uint8_t(Z)) << 8);
|
||||
};
|
||||
|
||||
Local4_u left() const { return Local4_u{uint8_t(uint16_t(X) >> 2), uint8_t(uint16_t(Y) >> 2), uint8_t(uint16_t(Z) >> 2)}; }
|
||||
Local4_u right() const { return Local4_u{uint8_t(uint16_t(X) & 0b11), uint8_t(uint16_t(Y) & 0b11), uint8_t(uint16_t(Z) & 0b11)}; }
|
||||
};
|
||||
|
||||
struct Local256 {
|
||||
int8_t X : 8, Y : 8, Z : 8;
|
||||
|
||||
auto operator<=>(const Local256&) const = default;
|
||||
};
|
||||
|
||||
struct Local256_u {
|
||||
uint8_t X : 8, Y : 8, Z : 8;
|
||||
|
||||
auto operator<=>(const Local256_u&) const = default;
|
||||
};
|
||||
|
||||
struct Local4096 {
|
||||
int16_t X : 12, Y : 12, Z : 12;
|
||||
|
||||
auto operator<=>(const Local4096&) const = default;
|
||||
};
|
||||
|
||||
struct Local4096_u {
|
||||
uint16_t X : 12, Y : 12, Z : 12;
|
||||
|
||||
auto operator<=>(const Local4096_u&) const = default;
|
||||
};
|
||||
|
||||
struct GlobalVoxel {
|
||||
int32_t X : 24, Y : 24, Z : 24;
|
||||
|
||||
auto operator<=>(const GlobalVoxel&) const = default;
|
||||
};
|
||||
|
||||
struct GlobalNode {
|
||||
int32_t X : 20, Y : 20, Z : 20;
|
||||
|
||||
using Key = uint64_t;
|
||||
operator Key() const {
|
||||
return Key(uint32_t(X)) | (Key(uint32_t(Y) << 20)) | (Key(uint32_t(Z)) << 40);
|
||||
};
|
||||
|
||||
auto operator<=>(const GlobalNode&) const = default;
|
||||
};
|
||||
|
||||
struct GlobalChunk {
|
||||
int16_t X, Y, Z;
|
||||
|
||||
using Key = uint64_t;
|
||||
operator Key() const {
|
||||
return Key(uint16_t(X)) | (Key(uint16_t(Y)) << 16) | (Key(uint16_t(Z)) << 32);
|
||||
};
|
||||
|
||||
operator glm::i16vec3() const {
|
||||
return {X, Y, Z};
|
||||
return out;
|
||||
}
|
||||
|
||||
auto operator<=>(const GlobalChunk&) const = default;
|
||||
BitVec3& operator+=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) += value;
|
||||
|
||||
Local16_u toLocal() const {
|
||||
return Local16_u(X & 0xf, Y & 0xf, Z & 0xf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator-(const BitVec3 &other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) - other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator-=(const BitVec3 &other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) -= other[iter];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator-(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) - value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator-=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) -= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator*(const BitVec3 &other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) * other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator*=(const BitVec3 &other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) *= other[iter];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator*(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) * value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator*=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) *= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator/(const BitVec3 &other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) / other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator/=(const BitVec3 &other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) /= other[iter];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator/(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) / value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator/=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) /= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator>>(const auto offset) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out.set(iter, get(iter) >> offset);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator>>=(const auto offset) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) >>= offset;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator<<(const auto offset) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) << offset;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator<<=(const auto offset) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) <<= offset;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator|(const BitVec3 other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) | other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator|=(const BitVec3 other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) |= other[iter];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator|(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) | value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator|=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) |= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator&(const BitVec3 other) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) & other[iter];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator&=(const BitVec3 other) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) &= other[iter];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVec3 operator&(const T value) const {
|
||||
BitVec3 out;
|
||||
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
out[iter] = get(iter) & value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
BitVec3& operator&=(const T value) {
|
||||
for(size_t iter = 0; iter < N; iter++)
|
||||
get(iter) &= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr size_t length() { return N; }
|
||||
};
|
||||
|
||||
struct GlobalRegion {
|
||||
int16_t X : 12, Y : 12, Z : 12;
|
||||
using bvec4i = BitVec3<int8_t, 2>;
|
||||
using bvec4u = BitVec3<uint8_t, 2>;
|
||||
using bvec16i = BitVec3<int8_t, 4>;
|
||||
using bvec16u = BitVec3<uint8_t, 4>;
|
||||
using bvec256i = BitVec3<int8_t, 8>;
|
||||
using bvec256u = BitVec3<uint8_t, 8>;
|
||||
using bvec4096i = BitVec3<int8_t, 12>;
|
||||
using bvec4096u = BitVec3<uint16_t, 12>;
|
||||
|
||||
using Key = uint64_t;
|
||||
operator Key() const {
|
||||
return Key(uint16_t(X)) | (Key(uint16_t(Y) << 12)) | (Key(uint16_t(Z)) << 24);
|
||||
};
|
||||
|
||||
auto operator<=>(const GlobalRegion&) const = default;
|
||||
|
||||
void fromChunk(const GlobalChunk &posChunk) {
|
||||
X = posChunk.X >> 4;
|
||||
Y = posChunk.Y >> 4;
|
||||
Z = posChunk.Z >> 4;
|
||||
}
|
||||
|
||||
GlobalChunk toChunk() const {
|
||||
return GlobalChunk(uint16_t(X) << 4, uint16_t(Y) << 4, uint16_t(Z) << 4);
|
||||
}
|
||||
|
||||
GlobalChunk toChunk(const Pos::Local16_u &posLocal) const {
|
||||
return GlobalChunk(
|
||||
(uint16_t(X) << 4) | posLocal.X,
|
||||
(uint16_t(Y) << 4) | posLocal.Y,
|
||||
(uint16_t(Z) << 4) | posLocal.Z
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
using Object = glm::i32vec3;
|
||||
using GlobalVoxel = BitVec3<int32_t, 24>;
|
||||
using GlobalNode = BitVec3<int32_t, 20>;
|
||||
using GlobalChunk = BitVec3<int16_t, 16>;
|
||||
using GlobalRegion = BitVec3<int16_t, 14>;
|
||||
using Object = BitVec3<int32_t, 32>;
|
||||
|
||||
struct Object_t {
|
||||
// Позиции объектов целочисленные, BS единиц это один метр
|
||||
static constexpr int32_t BS = 4096, BS_Bit = 12;
|
||||
|
||||
static glm::vec3 asFloatVec(Object &obj) { return glm::vec3(float(obj.x)/float(BS), float(obj.y)/float(BS), float(obj.z)/float(BS)); }
|
||||
static GlobalNode asNodePos(Object &obj) { return GlobalNode(obj.x >> BS_Bit, obj.y >> BS_Bit, obj.z >> BS_Bit); }
|
||||
static GlobalChunk asChunkPos(Object &obj) { return GlobalChunk(obj.x >> BS_Bit >> 4, obj.y >> BS_Bit >> 4, obj.z >> BS_Bit >> 4); }
|
||||
static GlobalChunk asRegionsPos(Object &obj) { return GlobalChunk(obj.x >> BS_Bit >> 8, obj.y >> BS_Bit >> 8, obj.z >> BS_Bit >> 8); }
|
||||
static glm::vec3 asFloatVec(const Object &obj) { return glm::vec3(float(obj[0])/float(BS), float(obj[1])/float(BS), float(obj[2])/float(BS)); }
|
||||
static GlobalNode asNodePos(const Object &obj) { return (GlobalNode) (obj >> BS_Bit); }
|
||||
static GlobalChunk asChunkPos(const Object &obj) { return (GlobalChunk) (obj >> BS_Bit >> 4); }
|
||||
static GlobalRegion asRegionsPos(const Object &obj) { return (GlobalRegion) (obj >> BS_Bit >> 8); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct LightPrism {
|
||||
uint8_t R : 2, G : 2, B : 2;
|
||||
|
||||
using ResourceId_t = uint32_t;
|
||||
|
||||
/*
|
||||
Bin привязывается к путю. Если по путю обновляется объект, пересчитывается его кеш и на клиентах обновляется
|
||||
*/
|
||||
|
||||
enum class EnumBinResource {
|
||||
Texture, Animation, Model, Sound, Font
|
||||
};
|
||||
|
||||
// Идентификаторы на стороне клиента
|
||||
using TextureId_c = uint16_t;
|
||||
using SoundId_c = uint16_t;
|
||||
using ModelId_c = uint16_t;
|
||||
using BinaryResource = std::shared_ptr<const std::u8string>;
|
||||
|
||||
using DefWorldId_c = uint8_t;
|
||||
using DefVoxelId_c = uint16_t;
|
||||
using DefNodeId_c = uint16_t;
|
||||
using DefPortalId_c = uint8_t;
|
||||
using WorldId_c = uint8_t;
|
||||
using PortalId_c = uint8_t;
|
||||
using DefEntityId_c = uint16_t;
|
||||
using EntityId_c = uint16_t;
|
||||
// Двоичные данные
|
||||
using BinTextureId_t = ResourceId_t;
|
||||
using BinAnimationId_t = ResourceId_t;
|
||||
using BinModelId_t = ResourceId_t;
|
||||
using BinSoundId_t = ResourceId_t;
|
||||
using BinFontId_t = ResourceId_t;
|
||||
|
||||
// Шаблоны использования бинарных ресурсов
|
||||
using TextureId_t = ResourceId_t;
|
||||
using AnimationId_t = ResourceId_t;
|
||||
using ModelId_t = ResourceId_t;
|
||||
using SoundId_t = ResourceId_t;
|
||||
using FontId_t = ResourceId_t;
|
||||
|
||||
enum class EnumDefContent {
|
||||
Voxel, Node, Generator, World, Portal, Entity, FuncEntitry
|
||||
};
|
||||
|
||||
// Игровые определения
|
||||
using DefVoxelId_t = ResourceId_t;
|
||||
using DefNodeId_t = ResourceId_t;
|
||||
using DefGeneratorId_t = ResourceId_t;
|
||||
using DefWorldId_t = ResourceId_t;
|
||||
using DefPortalId_t = ResourceId_t;
|
||||
using DefEntityId_t = ResourceId_t;
|
||||
using DefFuncEntityId_t = ResourceId_t;
|
||||
|
||||
|
||||
// Контент, основанный на игровых определениях
|
||||
using WorldId_t = ResourceId_t;
|
||||
using PortalId_t = ResourceId_t;
|
||||
|
||||
// struct LightPrism {
|
||||
// uint8_t R : 2, G : 2, B : 2;
|
||||
// };
|
||||
|
||||
}
|
||||
|
||||
@@ -174,12 +420,23 @@ using EntityId_c = uint16_t;
|
||||
|
||||
namespace std {
|
||||
|
||||
#define hash_for_pos(type) template <> struct hash<LV::Pos::type> { std::size_t operator()(const LV::Pos::type& obj) const { return std::hash<LV::Pos::type::Key>()((LV::Pos::type::Key) obj); } };
|
||||
hash_for_pos(Local4_u)
|
||||
hash_for_pos(Local16_u)
|
||||
hash_for_pos(Local16)
|
||||
hash_for_pos(GlobalChunk)
|
||||
hash_for_pos(GlobalRegion)
|
||||
#undef hash_for_pos
|
||||
template<typename T, size_t BitsPerComponent>
|
||||
struct hash<LV::Pos::BitVec3<T, BitsPerComponent>> {
|
||||
std::size_t operator()(const LV::Pos::BitVec3<T, BitsPerComponent>& obj) const {
|
||||
std::size_t result = 0;
|
||||
constexpr std::size_t seed = 0x9E3779B9;
|
||||
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
T value = obj[i];
|
||||
|
||||
std::hash<T> hasher;
|
||||
std::size_t h = hasher(value);
|
||||
|
||||
result ^= h + seed + (result << 6) + (result >> 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ bool calcBoxToBoxCollide(const VecType vec1_min, const VecType vec1_max,
|
||||
const VecType vec2_min, const VecType vec2_max, bool axis[VecType::length()] = nullptr
|
||||
) {
|
||||
|
||||
using ValType = VecType::value_type;
|
||||
using ValType = VecType::Type;
|
||||
|
||||
ValType max_delta = 0;
|
||||
ValType result = 0;
|
||||
|
||||
@@ -8,40 +8,19 @@
|
||||
|
||||
namespace LV::Server {
|
||||
|
||||
using ResourceId_t = uint32_t;
|
||||
|
||||
// Двоичные данные
|
||||
using BinTextureId_t = ResourceId_t;
|
||||
using BinSoundId_t = ResourceId_t;
|
||||
using BinModelId_t = ResourceId_t;
|
||||
|
||||
// Игровые определения
|
||||
using DefWorldId_t = ResourceId_t;
|
||||
using DefVoxelId_t = ResourceId_t;
|
||||
using DefNodeId_t = ResourceId_t;
|
||||
using DefPortalId_t = ResourceId_t;
|
||||
using DefEntityId_t = ResourceId_t;
|
||||
|
||||
|
||||
// Контент, основанный на игровых определениях
|
||||
using WorldId_t = ResourceId_t;
|
||||
|
||||
// В одном регионе может быть максимум 2^16 сущностей. Клиенту адресуются сущности в формате <мир>+<позиция региона>+<uint16_t>
|
||||
// И если сущность перешла из одного региона в другой, идентификатор сущности на стороне клиента сохраняется
|
||||
using LocalEntityId_t = uint16_t;
|
||||
using GlobalEntityId_t = std::tuple<WorldId_t, Pos::GlobalRegion, LocalEntityId_t>;
|
||||
using PortalId_t = uint16_t;
|
||||
|
||||
|
||||
using EntityId_t = uint16_t;
|
||||
using FuncEntityId_t = uint16_t;
|
||||
using ClientEntityId_t = std::tuple<WorldId_t, Pos::GlobalRegion, EntityId_t>;
|
||||
|
||||
using MediaStreamId_t = uint16_t;
|
||||
using ContentBridgeId_t = uint16_t;
|
||||
using PlayerId_t = uint32_t;
|
||||
using ContentBridgeId_t = ResourceId_t;
|
||||
using PlayerId_t = ResourceId_t;
|
||||
|
||||
|
||||
/*
|
||||
Сервер загружает информацию о локальных текстурах
|
||||
Синхронизация часто используемых текстур?
|
||||
Пересмотр списка текстур?
|
||||
Динамичные текстуры?
|
||||
|
||||
@@ -66,13 +45,13 @@ struct ServerTime {
|
||||
|
||||
struct VoxelCube {
|
||||
DefVoxelId_t VoxelId;
|
||||
Pos::Local256_u Left, Right;
|
||||
Pos::bvec256u Left, Right;
|
||||
|
||||
auto operator<=>(const VoxelCube&) const = default;
|
||||
};
|
||||
|
||||
struct VoxelCube_Region {
|
||||
Pos::Local4096_u Left, Right;
|
||||
Pos::bvec4096u Left, Right;
|
||||
DefVoxelId_t VoxelId;
|
||||
|
||||
auto operator<=>(const VoxelCube_Region&) const = default;
|
||||
@@ -88,13 +67,13 @@ struct AABB {
|
||||
Pos::Object VecMin, VecMax;
|
||||
|
||||
void sortMinMax() {
|
||||
Pos::Object::value_type left, right;
|
||||
Pos::Object::Type left, right;
|
||||
|
||||
for(int iter = 0; iter < 3; iter++) {
|
||||
left = std::min(VecMin[iter], VecMax[iter]);
|
||||
right = std::max(VecMin[iter], VecMax[iter]);
|
||||
VecMin[iter] = left;
|
||||
VecMax[iter] = right;
|
||||
VecMin.set(iter, left);
|
||||
VecMax.set(iter, right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,15 +101,19 @@ struct CollisionAABB : public AABB {
|
||||
|
||||
union {
|
||||
struct {
|
||||
LocalEntityId_t Index;
|
||||
EntityId_t Index;
|
||||
} Entity;
|
||||
|
||||
struct {
|
||||
Pos::Local16_u Pos;
|
||||
FuncEntityId_t Index;
|
||||
} FuncEntity;
|
||||
|
||||
struct {
|
||||
Pos::bvec16u Pos;
|
||||
} Node;
|
||||
|
||||
struct {
|
||||
Pos::Local16_u Chunk;
|
||||
Pos::bvec16u Chunk;
|
||||
uint32_t Index;
|
||||
DefVoxelId_t Id;
|
||||
} Voxel;
|
||||
@@ -197,9 +180,9 @@ struct VoxelCuboidsFuncs {
|
||||
if (a.VoxelId != b.VoxelId) return false;
|
||||
|
||||
// Проверяем, что кубы смежны по одной из осей
|
||||
bool xAdjacent = (a.Right.X == b.Left.X) && (a.Left.Y == b.Left.Y) && (a.Right.Y == b.Right.Y) && (a.Left.Z == b.Left.Z) && (a.Right.Z == b.Right.Z);
|
||||
bool yAdjacent = (a.Right.Y == b.Left.Y) && (a.Left.X == b.Left.X) && (a.Right.X == b.Right.X) && (a.Left.Z == b.Left.Z) && (a.Right.Z == b.Right.Z);
|
||||
bool zAdjacent = (a.Right.Z == b.Left.Z) && (a.Left.X == b.Left.X) && (a.Right.X == b.Right.X) && (a.Left.Y == b.Left.Y) && (a.Right.Y == b.Right.Y);
|
||||
bool xAdjacent = (a.Right.x == b.Left.x) && (a.Left.y == b.Left.y) && (a.Right.z == b.Right.z) && (a.Left.z == b.Left.z) && (a.Right.z == b.Right.z);
|
||||
bool yAdjacent = (a.Right.y == b.Left.y) && (a.Left.x == b.Left.x) && (a.Right.x == b.Right.x) && (a.Left.z == b.Left.z) && (a.Right.z == b.Right.z);
|
||||
bool zAdjacent = (a.Right.z == b.Left.z) && (a.Left.x == b.Left.x) && (a.Right.x == b.Right.x) && (a.Left.y == b.Left.y) && (a.Right.y == b.Right.y);
|
||||
|
||||
return xAdjacent || yAdjacent || zAdjacent;
|
||||
}
|
||||
@@ -209,13 +192,13 @@ struct VoxelCuboidsFuncs {
|
||||
merged.VoxelId = a.VoxelId;
|
||||
|
||||
// Объединяем кубы по минимальным и максимальным координатам
|
||||
merged.Left.X = std::min(a.Left.X, b.Left.X);
|
||||
merged.Left.Y = std::min(a.Left.Y, b.Left.Y);
|
||||
merged.Left.Z = std::min(a.Left.Z, b.Left.Z);
|
||||
merged.Left.x = std::min(a.Left.x, b.Left.x);
|
||||
merged.Left.y = std::min(a.Left.y, b.Left.y);
|
||||
merged.Left.z = std::min(a.Left.z, b.Left.z);
|
||||
|
||||
merged.Right.X = std::max(a.Right.X, b.Right.X);
|
||||
merged.Right.Y = std::max(a.Right.Y, b.Right.Y);
|
||||
merged.Right.Z = std::max(a.Right.Z, b.Right.Z);
|
||||
merged.Right.x = std::max(a.Right.x, b.Right.x);
|
||||
merged.Right.y = std::max(a.Right.y, b.Right.y);
|
||||
merged.Right.z = std::max(a.Right.z, b.Right.z);
|
||||
|
||||
return merged;
|
||||
}
|
||||
@@ -311,25 +294,25 @@ struct VoxelCuboidsFuncs {
|
||||
|
||||
inline void convertRegionVoxelsToChunks(const std::vector<VoxelCube_Region>& regions, std::vector<VoxelCube> *chunks) {
|
||||
for (const auto& region : regions) {
|
||||
int minX = region.Left.X >> 8;
|
||||
int minY = region.Left.Y >> 8;
|
||||
int minZ = region.Left.Z >> 8;
|
||||
int maxX = region.Right.X >> 8;
|
||||
int maxY = region.Right.Y >> 8;
|
||||
int maxZ = region.Right.Z >> 8;
|
||||
int minX = region.Left.x >> 8;
|
||||
int minY = region.Left.y >> 8;
|
||||
int minZ = region.Left.z >> 8;
|
||||
int maxX = region.Right.x >> 8;
|
||||
int maxY = region.Right.y >> 8;
|
||||
int maxZ = region.Right.z >> 8;
|
||||
|
||||
for (int x = minX; x <= maxX; ++x) {
|
||||
for (int y = minY; y <= maxY; ++y) {
|
||||
for (int z = minZ; z <= maxZ; ++z) {
|
||||
Pos::Local256_u left {
|
||||
static_cast<uint8_t>(std::max<uint16_t>((x << 8), region.Left.X) - (x << 8)),
|
||||
static_cast<uint8_t>(std::max<uint16_t>((y << 8), region.Left.Y) - (y << 8)),
|
||||
static_cast<uint8_t>(std::max<uint16_t>((z << 8), region.Left.Z) - (z << 8))
|
||||
Pos::bvec256u left {
|
||||
static_cast<uint8_t>(std::max<uint16_t>((x << 8), region.Left.x) - (x << 8)),
|
||||
static_cast<uint8_t>(std::max<uint16_t>((y << 8), region.Left.y) - (y << 8)),
|
||||
static_cast<uint8_t>(std::max<uint16_t>((z << 8), region.Left.z) - (z << 8))
|
||||
};
|
||||
Pos::Local256_u right {
|
||||
static_cast<uint8_t>(std::min<uint16_t>(((x+1) << 8)-1, region.Right.X) - (x << 8)),
|
||||
static_cast<uint8_t>(std::min<uint16_t>(((y+1) << 8)-1, region.Right.Y) - (y << 8)),
|
||||
static_cast<uint8_t>(std::min<uint16_t>(((z+1) << 8)-1, region.Right.Z) - (z << 8))
|
||||
Pos::bvec256u right {
|
||||
static_cast<uint8_t>(std::min<uint16_t>(((x+1) << 8)-1, region.Right.x) - (x << 8)),
|
||||
static_cast<uint8_t>(std::min<uint16_t>(((y+1) << 8)-1, region.Right.y) - (y << 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;
|
||||
@@ -346,12 +329,12 @@ inline void convertChunkVoxelsToRegion(const std::vector<VoxelCube> *chunks, std
|
||||
for (int z = 0; z < 16; ++z) {
|
||||
int chunkIndex = z * 16 * 16 + y * 16 + x;
|
||||
|
||||
Pos::Local4096_u left(x << 8, y << 8, z << 8);
|
||||
Pos::bvec4096u left(x << 8, y << 8, z << 8);
|
||||
|
||||
for (const auto& cube : chunks[chunkIndex]) {
|
||||
regions.emplace_back(
|
||||
Pos::Local4096_u(left.X+cube.Left.X, left.Y+cube.Left.Y, left.Z+cube.Left.Z),
|
||||
Pos::Local4096_u(left.X+cube.Right.X, left.Y+cube.Right.Y, left.Z+cube.Right.Z),
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user