*
This commit is contained in:
@@ -1594,7 +1594,7 @@ PreparedModel::PreparedModel(const std::string_view modid, const js::object& pro
|
||||
const js::object& textures = textures_val->as_object();
|
||||
|
||||
for(const auto& [key, value] : textures) {
|
||||
Textures[key] = value.as_string();
|
||||
Textures[key] = compileTexturePipeline((std::string) value.as_string(), modid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1634,20 +1634,20 @@ PreparedModel::PreparedModel(const std::string_view modid, const js::object& pro
|
||||
const js::object& faces = cuboid.at("faces").as_object();
|
||||
|
||||
for(const auto& [key, value] : faces) {
|
||||
Cuboid::EnumFace type;
|
||||
EnumFace type;
|
||||
|
||||
if(key == "down")
|
||||
type = Cuboid::EnumFace::Down;
|
||||
type = EnumFace::Down;
|
||||
else if(key == "up")
|
||||
type = Cuboid::EnumFace::Up;
|
||||
type = EnumFace::Up;
|
||||
else if(key == "north")
|
||||
type = Cuboid::EnumFace::North;
|
||||
type = EnumFace::North;
|
||||
else if(key == "south")
|
||||
type = Cuboid::EnumFace::South;
|
||||
type = EnumFace::South;
|
||||
else if(key == "west")
|
||||
type = Cuboid::EnumFace::West;
|
||||
type = EnumFace::West;
|
||||
else if(key == "east")
|
||||
type = Cuboid::EnumFace::East;
|
||||
type = EnumFace::East;
|
||||
else
|
||||
MAKE_ERROR("Unknown face");
|
||||
|
||||
@@ -1671,17 +1671,17 @@ PreparedModel::PreparedModel(const std::string_view modid, const js::object& pro
|
||||
const std::string_view cullface = cullface_val->as_string();
|
||||
|
||||
if(cullface == "down")
|
||||
face.Cullface = Cuboid::EnumFace::Down;
|
||||
face.Cullface = EnumFace::Down;
|
||||
else if(cullface == "up")
|
||||
face.Cullface = Cuboid::EnumFace::Up;
|
||||
face.Cullface = EnumFace::Up;
|
||||
else if(cullface == "north")
|
||||
face.Cullface = Cuboid::EnumFace::North;
|
||||
face.Cullface = EnumFace::North;
|
||||
else if(cullface == "south")
|
||||
face.Cullface = Cuboid::EnumFace::South;
|
||||
face.Cullface = EnumFace::South;
|
||||
else if(cullface == "west")
|
||||
face.Cullface = Cuboid::EnumFace::West;
|
||||
face.Cullface = EnumFace::West;
|
||||
else if(cullface == "east")
|
||||
face.Cullface = Cuboid::EnumFace::East;
|
||||
face.Cullface = EnumFace::East;
|
||||
else
|
||||
MAKE_ERROR("Unknown face");
|
||||
}
|
||||
@@ -1721,17 +1721,17 @@ PreparedModel::PreparedModel(const std::string_view modid, const js::object& pro
|
||||
}
|
||||
|
||||
if(key == "x")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::MoveX, f_value);
|
||||
result.Transformations.emplace_back(Transformation::MoveX, f_value);
|
||||
else if(key == "y")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::MoveY, f_value);
|
||||
result.Transformations.emplace_back(Transformation::MoveY, f_value);
|
||||
else if(key == "z")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::MoveZ, f_value);
|
||||
result.Transformations.emplace_back(Transformation::MoveZ, f_value);
|
||||
else if(key == "rx")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::RotateX, f_value);
|
||||
result.Transformations.emplace_back(Transformation::RotateX, f_value);
|
||||
else if(key == "ry")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::RotateY, f_value);
|
||||
result.Transformations.emplace_back(Transformation::RotateY, f_value);
|
||||
else if(key == "rz")
|
||||
result.Transformations.emplace_back(Cuboid::Transformation::RotateZ, f_value);
|
||||
result.Transformations.emplace_back(Transformation::RotateZ, f_value);
|
||||
else
|
||||
MAKE_ERROR("Неизвестный ключ трансформации");
|
||||
}
|
||||
@@ -1813,7 +1813,17 @@ PreparedModel::PreparedModel(const std::u8string& data) {
|
||||
for(int counter = 0; counter < size; counter++) {
|
||||
std::string tkey, pipeline;
|
||||
lr >> tkey >> pipeline;
|
||||
Textures.insert({tkey, pipeline});
|
||||
TexturePipeline pipe;
|
||||
|
||||
uint16_t size;
|
||||
lr >> size;
|
||||
pipe.BinTextures.reserve(size);
|
||||
for(int iter = 0; iter < size; iter++)
|
||||
pipe.BinTextures.push_back(lr.read<ResourceId>());
|
||||
|
||||
lr >> (std::string&) pipe.Pipeline;
|
||||
|
||||
CompiledTextures.insert({tkey, std::move(pipe)});
|
||||
}
|
||||
|
||||
lr >> size;
|
||||
@@ -1843,12 +1853,12 @@ PreparedModel::PreparedModel(const std::u8string& data) {
|
||||
lr >> face.Texture;
|
||||
uint8_t val = lr.read<uint8_t>();
|
||||
if(val != uint8_t(-1)) {
|
||||
face.Cullface = Cuboid::EnumFace(val);
|
||||
face.Cullface = EnumFace(val);
|
||||
}
|
||||
|
||||
lr >> face.TintIndex >> face.Rotation;
|
||||
|
||||
cuboid.Faces.insert({(Cuboid::EnumFace) type, face});
|
||||
cuboid.Faces.insert({(EnumFace) type, face});
|
||||
}
|
||||
|
||||
uint16_t transformationsSize;
|
||||
@@ -1856,8 +1866,8 @@ PreparedModel::PreparedModel(const std::u8string& data) {
|
||||
cuboid.Transformations.reserve(transformationsSize);
|
||||
|
||||
for(int counter2 = 0; counter2 < transformationsSize; counter2++) {
|
||||
Cuboid::Transformation tsf;
|
||||
tsf.Op = (Cuboid::Transformation::EnumTransform) lr.read<uint8_t>();
|
||||
Transformation tsf;
|
||||
tsf.Op = (Transformation::EnumTransform) lr.read<uint8_t>();
|
||||
lr >> tsf.Value;
|
||||
cuboid.Transformations.emplace_back(tsf);
|
||||
}
|
||||
@@ -1882,6 +1892,8 @@ PreparedModel::PreparedModel(const std::u8string& data) {
|
||||
std::u8string PreparedModel::dump() const {
|
||||
Net::Packet result;
|
||||
|
||||
result << 'b' << 'm';
|
||||
|
||||
if(GuiLight.has_value()) {
|
||||
result << uint8_t(1);
|
||||
result << uint8_t(GuiLight.value());
|
||||
@@ -1916,12 +1928,19 @@ std::u8string PreparedModel::dump() const {
|
||||
assert(Textures.size() < (1 << 16));
|
||||
result << uint16_t(Textures.size());
|
||||
|
||||
for(const auto& [tkey, dk] : Textures) {
|
||||
assert(CompiledTextures.size() == Textures.size());
|
||||
|
||||
for(const auto& [tkey, dk] : CompiledTextures) {
|
||||
assert(tkey.size() < 32);
|
||||
result << tkey;
|
||||
|
||||
assert(dk.size() < 512);
|
||||
result << dk;
|
||||
assert(dk.BinTextures.size() < 512);
|
||||
result << uint16_t(dk.BinTextures.size());
|
||||
for(size_t iter = 0; iter < dk.BinTextures.size(); iter++) {
|
||||
result << dk.BinTextures[iter];
|
||||
}
|
||||
|
||||
result << (const std::string&) dk.Pipeline;
|
||||
}
|
||||
|
||||
assert(Cuboids.size() < (1 << 16));
|
||||
@@ -1976,6 +1995,36 @@ std::u8string PreparedModel::dump() const {
|
||||
return result.complite();
|
||||
}
|
||||
|
||||
PreparedGLTF::PreparedGLTF(const std::string_view modid, const js::object& gltf) {
|
||||
// gltf
|
||||
|
||||
// Сцена по умолчанию
|
||||
// Сцены -> Ноды
|
||||
// Ноды -> Ноды, меши, матрицы, translation, rotation
|
||||
// Меши -> Примитивы
|
||||
// Примитивы -> Материал, вершинные данные
|
||||
// Материалы -> текстуры
|
||||
// Текстуры
|
||||
// Буферы
|
||||
}
|
||||
|
||||
PreparedGLTF::PreparedGLTF(const std::string_view modid, Resource glb) {
|
||||
|
||||
}
|
||||
|
||||
PreparedGLTF::PreparedGLTF(std::u8string_view data) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::u8string PreparedGLTF::dump() const {
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
void PreparedGLTF::load(std::u8string_view data) {
|
||||
|
||||
}
|
||||
|
||||
struct Resource::InlineMMap {
|
||||
boost::interprocess::file_mapping MMap;
|
||||
boost::interprocess::mapped_region Region;
|
||||
|
||||
@@ -391,6 +391,7 @@ struct Object_t {
|
||||
|
||||
|
||||
using ResourceId = uint32_t;
|
||||
struct Resource;
|
||||
|
||||
/*
|
||||
Объекты, собранные из папки assets или зарегистрированные модами.
|
||||
@@ -495,6 +496,43 @@ void unCompressNodes(const std::u8string& compressed, Node* ptr);
|
||||
std::u8string compressLinear(const std::u8string& data);
|
||||
std::u8string unCompressLinear(const std::u8string& data);
|
||||
|
||||
inline std::pair<std::string, std::string> parseDomainKey(const std::string& value, const std::string_view defaultDomain = "core") {
|
||||
auto regResult = TOS::Str::match(value, "(?:([\\w\\d_]+):)?([\\w\\d/_.]+)");
|
||||
if(!regResult)
|
||||
MAKE_ERROR("Недействительный домен:ключ");
|
||||
|
||||
if(regResult->at(1)) {
|
||||
return std::pair<std::string, std::string>{*regResult->at(1), *regResult->at(2)};
|
||||
} else {
|
||||
return std::pair<std::string, std::string>{defaultDomain, *regResult->at(2)};
|
||||
}
|
||||
}
|
||||
|
||||
struct PrecompiledTexturePipeline {
|
||||
// Локальные идентификаторы пайплайна в домен+ключ
|
||||
std::vector<std::pair<std::string, std::string>> Assets;
|
||||
// Чистый код текстурных преобразований, локальные идентификаторы связаны с Assets
|
||||
std::u8string Pipeline;
|
||||
};
|
||||
|
||||
struct TexturePipeline {
|
||||
// Разыменованые идентификаторы
|
||||
std::vector<AssetsTexture> BinTextures;
|
||||
// Чистый код текстурных преобразований, локальные идентификаторы связаны с BinTextures
|
||||
std::u8string Pipeline;
|
||||
};
|
||||
|
||||
// Компилятор текстурных потоков
|
||||
inline PrecompiledTexturePipeline compileTexturePipeline(const std::string &cmd, const std::string_view defaultDomain = "core") {
|
||||
PrecompiledTexturePipeline result;
|
||||
|
||||
auto [domain, key] = parseDomainKey(cmd, defaultDomain);
|
||||
|
||||
result.Assets.emplace_back(domain, key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct NodestateEntry {
|
||||
std::string Name;
|
||||
int Variability = 0; // Количество возможный значений состояния
|
||||
@@ -585,6 +623,22 @@ private:
|
||||
std::vector<Transformation> parseTransormations(const js::array& arr);
|
||||
};
|
||||
|
||||
|
||||
enum class EnumFace {
|
||||
Down, Up, North, South, West, East, None
|
||||
};
|
||||
|
||||
struct Transformation {
|
||||
enum EnumTransform {
|
||||
MoveX, MoveY, MoveZ,
|
||||
RotateX, RotateY, RotateZ,
|
||||
ScaleX, ScaleY, ScaleZ,
|
||||
MAX_ENUM
|
||||
} Op;
|
||||
|
||||
float Value;
|
||||
};
|
||||
|
||||
/*
|
||||
Парсит json модель
|
||||
*/
|
||||
@@ -604,16 +658,13 @@ struct PreparedModel {
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, FullTransformation> Display;
|
||||
std::unordered_map<std::string, std::string> Textures;
|
||||
std::unordered_map<std::string, PrecompiledTexturePipeline> Textures;
|
||||
std::unordered_map<std::string, TexturePipeline> CompiledTextures;
|
||||
|
||||
struct Cuboid {
|
||||
bool Shade;
|
||||
glm::vec3 From, To;
|
||||
|
||||
enum class EnumFace {
|
||||
Down, Up, North, South, West, East
|
||||
};
|
||||
|
||||
struct Face {
|
||||
glm::vec4 UV;
|
||||
std::string Texture;
|
||||
@@ -623,16 +674,6 @@ struct PreparedModel {
|
||||
};
|
||||
|
||||
std::unordered_map<EnumFace, Face> Faces;
|
||||
|
||||
struct Transformation {
|
||||
enum EnumTransform {
|
||||
MoveX, MoveY, MoveZ,
|
||||
RotateX, RotateY, RotateZ,
|
||||
MAX_ENUM
|
||||
} Op;
|
||||
|
||||
float Value;
|
||||
};
|
||||
|
||||
std::vector<Transformation> Transformations;
|
||||
};
|
||||
@@ -662,7 +703,38 @@ struct PreparedModel {
|
||||
std::u8string dump() const;
|
||||
|
||||
private:
|
||||
bool load(const std::u8string& data) noexcept;
|
||||
void load(std::u8string_view data);
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
glm::vec3 Pos;
|
||||
glm::vec2 UV;
|
||||
uint32_t TexId;
|
||||
};
|
||||
|
||||
struct PreparedGLTF {
|
||||
std::vector<std::string> TextureKey;
|
||||
std::unordered_map<std::string, PrecompiledTexturePipeline> Textures;
|
||||
std::unordered_map<std::string, TexturePipeline> CompiledTextures;
|
||||
std::vector<Vertex> Vertices;
|
||||
|
||||
|
||||
PreparedGLTF(const std::string_view modid, const js::object& gltf);
|
||||
PreparedGLTF(const std::string_view modid, Resource glb);
|
||||
PreparedGLTF(std::u8string_view data);
|
||||
|
||||
PreparedGLTF() = default;
|
||||
PreparedGLTF(const PreparedGLTF&) = default;
|
||||
PreparedGLTF(PreparedGLTF&&) = default;
|
||||
|
||||
PreparedGLTF& operator=(const PreparedGLTF&) = default;
|
||||
PreparedGLTF& operator=(PreparedGLTF&&) = default;
|
||||
|
||||
// Пишет в сжатый двоичный формат
|
||||
std::u8string dump() const;
|
||||
|
||||
private:
|
||||
void load(std::u8string_view data);
|
||||
};
|
||||
|
||||
enum struct TexturePipelineCMD : uint8_t {
|
||||
@@ -672,43 +744,6 @@ enum struct TexturePipelineCMD : uint8_t {
|
||||
|
||||
using Hash_t = std::array<uint8_t, 32>;
|
||||
|
||||
inline std::pair<std::string, std::string> parseDomainKey(const std::string& value, const std::string_view defaultDomain = "core") {
|
||||
auto regResult = TOS::Str::match(value, "(?:([\\w\\d_]+):)?([\\w\\d/_.]+)");
|
||||
if(!regResult)
|
||||
MAKE_ERROR("Недействительный домен:ключ");
|
||||
|
||||
if(regResult->at(1)) {
|
||||
return std::pair<std::string, std::string>{*regResult->at(1), *regResult->at(2)};
|
||||
} else {
|
||||
return std::pair<std::string, std::string>{defaultDomain, *regResult->at(2)};
|
||||
}
|
||||
}
|
||||
|
||||
struct PrecompiledTexturePipeline {
|
||||
// Локальные идентификаторы пайплайна в домен+ключ
|
||||
std::vector<std::pair<std::string, std::string>> Assets;
|
||||
// Чистый код текстурных преобразований, локальные идентификаторы связаны с Assets
|
||||
std::u8string Pipeline;
|
||||
};
|
||||
|
||||
struct TexturePipeline {
|
||||
// Разыменованые идентификаторы
|
||||
std::vector<AssetsTexture> BinTextures;
|
||||
// Чистый код текстурных преобразований, локальные идентификаторы связаны с BinTextures
|
||||
std::u8string Pipeline;
|
||||
};
|
||||
|
||||
// Компилятор текстурных потоков
|
||||
inline PrecompiledTexturePipeline compileTexturePipeline(const std::string &cmd, const std::string_view defaultDomain = "core") {
|
||||
PrecompiledTexturePipeline result;
|
||||
|
||||
auto [domain, key] = parseDomainKey(cmd, defaultDomain);
|
||||
|
||||
result.Assets.emplace_back(domain, key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Resource {
|
||||
private:
|
||||
struct InlineMMap;
|
||||
|
||||
Reference in New Issue
Block a user