diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 852b2829..323be059 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -107,10 +107,6 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) { for (uint i = 0; i < 6; i++) { def->textureFaces[i] = texarr->str(i); } - for (uint i = 6; i < texarr->values.size(); i++) - { - def->textureMoreFaces.push_back(texarr->str(i)); - } } // block model @@ -119,13 +115,13 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) { if (model == "block") def->model = BlockModel::block; else if (model == "aabb") def->model = BlockModel::aabb; else if (model == "custom") { - def->model = BlockModel::customfaces; - json::JArray* pointarr = root->arr("faces-points"); - for (uint i = 0; i < pointarr->values.size(); i+=3) - { - def->customfacesPoints.push_back(glm::vec3(pointarr->num(i), - pointarr->num(i+1), - pointarr->num(i + 2))); + def->model = BlockModel::custom; + if (root->has("model-primitives")) { + loadCustomBlockModel(def, root->obj("model-primitives")); + } + else { + std::cerr << "ERROR occured while block " + << name << " parsed: no \"model-primitives\" found" << std::endl; } } else if (model == "X") def->model = BlockModel::xsprite; @@ -179,6 +175,51 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) { root->str("picking-item", def->pickingItem); } +void ContentLoader::loadCustomBlockModel(Block* def, json::JObject* primitives) { + if (primitives->has("aabbs")) { + json::JArray* modelboxes = primitives->arr("aabbs"); + for (uint i = 0; i < modelboxes->size(); i++ ) { + /* Parse aabb */ + json::JArray* boxobj = modelboxes->arr(i); + AABB modelbox; + modelbox.a = glm::vec3(boxobj->num(0), boxobj->num(1), boxobj->num(2)); + modelbox.b = glm::vec3(boxobj->num(3), boxobj->num(4), boxobj->num(5)); + modelbox.b += modelbox.a; + def->modelBoxes.push_back(modelbox); + + if (boxobj->size() == 7) + for (uint i = 6; i < 12; i++) { + def->modelTextures.push_back(boxobj->str(6)); + } + else if (boxobj->size() == 12) + for (uint i = 6; i < 12; i++) { + def->modelTextures.push_back(boxobj->str(i)); + } + else + for (uint i = 6; i < 12; i++) { + def->modelTextures.push_back("notfound"); + } + } + } + if (primitives->has("tetragons")) { + json::JArray* modeltetragons = primitives->arr("tetragons"); + for (uint i = 0; i < modeltetragons->size(); i++) { + /* Parse tetragon to points */ + json::JArray* tgonobj = modeltetragons->arr(i); + glm::vec3 p1(tgonobj->num(0), tgonobj->num(1), tgonobj->num(2)), + p2(tgonobj->num(3), tgonobj->num(4), tgonobj->num(5)), + p3(tgonobj->num(6), tgonobj->num(7), tgonobj->num(8)); + glm::vec3 p4 = p3 + (p1 - p2); + def->modelExtraPoints.push_back(p1); + def->modelExtraPoints.push_back(p2); + def->modelExtraPoints.push_back(p3); + def->modelExtraPoints.push_back(p4); + + def->modelTextures.push_back(tgonobj->str(9)); + } + } +} + void ContentLoader::loadItem(ItemDef* def, std::string name, std::filesystem::path file) { std::unique_ptr root(files::read_json(file)); } diff --git a/src/content/ContentLoader.h b/src/content/ContentLoader.h index 25b5104a..acdd4e2f 100644 --- a/src/content/ContentLoader.h +++ b/src/content/ContentLoader.h @@ -17,6 +17,7 @@ class ContentLoader { const ContentPack* pack; void loadBlock(Block* def, std::string full, std::string name); + void loadCustomBlockModel(Block* def, json::JObject* primitives); void loadItem(ItemDef* def, std::string full, std::string name); public: ContentLoader(ContentPack* pack); diff --git a/src/frontend/BlocksPreview.cpp b/src/frontend/BlocksPreview.cpp index 2d24faeb..10e23c66 100644 --- a/src/frontend/BlocksPreview.cpp +++ b/src/frontend/BlocksPreview.cpp @@ -59,7 +59,7 @@ void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tin batch->blockCube(def->hitbox.size() * glm::vec3(size * 0.63f), texfaces, tint, !def->rt.emissive); break; - case BlockModel::customfaces: + case BlockModel::custom: case BlockModel::xsprite: { glm::vec3 right = glm::normalize(glm::vec3(1.f, 0.f, -1.f)); batch->sprite(right*float(size)*0.43f+glm::vec3(0, size*0.4f, 0), diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 5b74a129..86c8541c 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -23,14 +23,14 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) { sideregions[i * 6 + side] = atlas->get("notfound"); } } - for (uint side = 0; side < def->textureMoreFaces.size(); side++) + for (uint side = 0; side < def->modelTextures.size(); side++) { - std::string tex = def->textureMoreFaces[side]; + std::string tex = def->modelTextures[side]; if (atlas->has(tex)) { - def->customfacesExtraUVs.push_back(atlas->get(tex)); + def->modelUVs.push_back(atlas->get(tex)); } else { if (atlas->has("notfound")) - def->customfacesExtraUVs.push_back(atlas->get("notfound")); + def->modelUVs.push_back(atlas->get("notfound")); } } } diff --git a/src/graphics/BlocksRenderer.cpp b/src/graphics/BlocksRenderer.cpp index 0c35ddaf..c9b32aef 100644 --- a/src/graphics/BlocksRenderer.cpp +++ b/src/graphics/BlocksRenderer.cpp @@ -230,35 +230,45 @@ void BlocksRenderer::blockAABB(const ivec3& icoord, face(coord, Z*size.z, Y*size.y, -X*size.x, texfaces[0], lights); // east } -void BlocksRenderer::blockCustomFaces(const ivec3& icoord, const UVRegion(&texfaces)[6], +void BlocksRenderer::blockCustomModel(const ivec3& icoord, const Block* block, ubyte rotation, bool lights) { const float tint = 1.0f; vec3 X(1, 0, 0); vec3 Y(0, 1, 0); vec3 Z(0, 0, 1); + CoordSystem orient(X,Y,Z); vec3 coord(icoord); if (block->rotatable) { auto& rotations = block->rotations; - auto& orient = rotations.variants[rotation]; + orient = rotations.variants[rotation]; X = orient.axisX; Y = orient.axisY; Z = orient.axisZ; } - - for (uint i = 0; i < 6; i++) - { - tetragonicFace(coord, - block->customfacesPoints[i * 4 + 0], - block->customfacesPoints[i * 4 + 1], - block->customfacesPoints[i * 4 + 2], - block->customfacesPoints[i * 4 + 3],X,Y,Z, texfaces[i], vec4(tint)); + + for (size_t i = 0; i < block->modelBoxes.size(); i++) { + AABB box = block->modelBoxes[i]; + vec3 size = box.size(); + if (block->rotatable) { + orient.transform(box); + } + vec3 center_coord = coord - vec3(0.5f) + box.center(); + face(center_coord, X * size.x, Y * size.y, Z * size.z, block->modelUVs[i * 6 + 5], lights); // north + face(center_coord, -X * size.x, Y * size.y, -Z * size.z, block->modelUVs[i * 6 + 4], lights); // south + face(center_coord, X * size.x, -Z * size.z, Y * size.y, block->modelUVs[i * 6 + 3], lights); // top + face(center_coord, -X * size.x, -Z * size.z, -Y * size.y, block->modelUVs[i * 6 + 2], lights); // bottom + face(center_coord, -Z * size.z, Y * size.y, X * size.x, block->modelUVs[i * 6 + 1], lights); // west + face(center_coord, Z * size.z, Y * size.y, -X * size.x, block->modelUVs[i * 6 + 0], lights); // east } - for (uint i = 0; i < block->textureMoreFaces.size(); i++) { + + for (size_t i = 0; i < block->modelExtraPoints.size()/4; i++) { tetragonicFace(coord, - block->customfacesPoints[i * 4 + 24], - block->customfacesPoints[i * 4 + 25], - block->customfacesPoints[i * 4 + 26], - block->customfacesPoints[i * 4 + 27], X, Y, Z, block->customfacesExtraUVs[i], vec4(tint)); + block->modelExtraPoints[i * 4 + 0], + block->modelExtraPoints[i * 4 + 1], + block->modelExtraPoints[i * 4 + 2], + block->modelExtraPoints[i * 4 + 3], + X, Y, Z, + block->modelUVs[block->modelBoxes.size()*6 + i], vec4(tint)); } } @@ -396,8 +406,8 @@ void BlocksRenderer::render(const voxel* voxels) { blockAABB(ivec3(x,y,z), texfaces, &def, vox.rotation(), !def.rt.emissive); break; } - case BlockModel::customfaces: { - blockCustomFaces(ivec3(x, y, z), texfaces, &def, vox.rotation(), !def.rt.emissive); + case BlockModel::custom: { + blockCustomModel(ivec3(x, y, z), &def, vox.rotation(), !def.rt.emissive); break; } default: diff --git a/src/graphics/BlocksRenderer.h b/src/graphics/BlocksRenderer.h index 176e32d3..0a93c431 100644 --- a/src/graphics/BlocksRenderer.h +++ b/src/graphics/BlocksRenderer.h @@ -77,8 +77,7 @@ class BlocksRenderer { ubyte rotation, bool lights); void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread); - void blockCustomFaces(const glm::ivec3& icoord, - const UVRegion(&texfaces)[6], + void blockCustomModel(const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights); diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 36ba498e..86534bfb 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -66,17 +66,20 @@ enum class BlockModel { block, // default shape xsprite, // X-shape (grass) aabb, // box shaped as block hitbox - customfaces // set of paired triangles (usual faces) + custom }; +using BoxModel = AABB; + class Block { public: std::string const name; // 0 1 2 3 4 5 std::string textureFaces[6]; // -x,x, -y,y, -z,z - std::vector textureMoreFaces = {}; - std::vector customfacesPoints = {}; - std::vector customfacesExtraUVs = {}; + std::vector modelTextures = {}; + std::vector modelBoxes = {}; + std::vector modelExtraPoints = {}; //initially made for tetragons + std::vector modelUVs = {}; // boxes' tex-UVs also there unsigned char emission[4] {0, 0, 0, 0}; unsigned char drawGroup = 0; BlockModel model = BlockModel::block;