diff --git a/res/content/base/blocks/wood.json b/res/content/base/blocks/wood.json index 2919c15d..e29d126a 100644 --- a/res/content/base/blocks/wood.json +++ b/res/content/base/blocks/wood.json @@ -7,5 +7,5 @@ "wood", "wood" ], - "rotatable": true + "rotation": "pipe" } \ No newline at end of file diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index ee91dfee..01db3ecd 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -52,6 +52,17 @@ Block* ContentLoader::loadBlock(string name, path file) { cerr << "unknown model " << model << endl; def->model = BlockModel::none; } + + // rotation profile + string profile = "none"; + root->str("rotation", profile); + def->rotatable = profile != "none"; + if (profile == "pipe") { + def->rotations = BlockRotProfile::PIPE; + } else if (profile != "none") { + cerr << "unknown rotation profile " << profile << endl; + def->rotatable = false; + } // block hitbox AABB [x, y, z, width, height, depth] json::JArray* hitboxobj = root->arr("hitbox"); @@ -76,7 +87,6 @@ Block* ContentLoader::loadBlock(string name, path file) { root->flag("light-passing", def->lightPassing); root->flag("breakable", def->breakable); root->flag("selectable", def->selectable); - root->flag("rotatable", def->rotatable); root->flag("sky-light-passing", def->skyLightPassing); root->num("draw-group", def->drawGroup); diff --git a/src/graphics/BlocksRenderer.cpp b/src/graphics/BlocksRenderer.cpp index ac0dca03..bfd52bb6 100644 --- a/src/graphics/BlocksRenderer.cpp +++ b/src/graphics/BlocksRenderer.cpp @@ -279,17 +279,13 @@ void BlocksRenderer::blockCubeShaded(int x, int y, int z, const UVRegion(&texfac ivec3 loff(0); ivec3 coord(x, y, z); if (block->rotatable) { - if (states == BLOCK_DIR_X) { - Y = {1, 0, 0}; - X = {0, -1, 0}; - coord.y++; - loff.y--; - } else if (states == BLOCK_DIR_Z) { - Y = {0, 0, 1}; - Z = {0, -1, 0}; - coord.z--; - loff.z++; - } + auto& rotations = block->rotations; + auto& orient = rotations.variants[states & BLOCK_ROT_MASK]; + X = orient.axisX; + Y = orient.axisY; + Z = orient.axisZ; + coord += orient.fix; + loff -= orient.fix; } if (isOpen(x+Z.x, y+Z.y, z+Z.z, group)) { diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index b1aa3a61..41602a26 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -1,10 +1,19 @@ #include "Block.h" +BlockRotProfile BlockRotProfile::PIPE {{ + // Vertical + {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}}, + // X-Aligned + {{0, -1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}}, + // Z-Aligned + {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}, {0, 0, -1}}, +}}; + Block::Block(std::string name) : name(name), textureFaces {"notfound","notfound","notfound", "notfound","notfound","notfound",} { - + rotations = BlockRotProfile::PIPE; } Block::Block(std::string name, std::string texture) : name(name), diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 832a4f2f..42fdf0cc 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -2,6 +2,7 @@ #define VOXELS_BLOCK_H_ #include +#include #include "../maths/aabb.h" #include "../typedefs.h" @@ -15,6 +16,23 @@ #define BLOCK_AABB_GRID 16 +struct CoordSystem { + glm::ivec3 axisX; + glm::ivec3 axisY; + glm::ivec3 axisZ; + // Grid 3d position fix offset (for negative vectors) + glm::ivec3 fix; +}; + +struct BlockRotProfile { + CoordSystem variants[16]; + + /* Wood logs, pillars, pipes + 3 orientations supported + */ + static BlockRotProfile PIPE; +}; + enum class BlockModel { none, // invisible block, // default shape @@ -38,6 +56,7 @@ public: bool breakable = true; bool rotatable = false; AABB hitbox; + BlockRotProfile rotations; struct { blockid_t id; diff --git a/src/voxels/voxel.h b/src/voxels/voxel.h index 774bcf07..66026f8b 100644 --- a/src/voxels/voxel.h +++ b/src/voxels/voxel.h @@ -4,8 +4,11 @@ #include "../typedefs.h" #define BLOCK_DIR_X 0x1 -#define BLOCK_DIR_Y 0x2 -#define BLOCK_DIR_Z 0x3 +#define BLOCK_DIR_Y 0x0 +#define BLOCK_DIR_Z 0x2 + +// limited to 16 block orientations +#define BLOCK_ROT_MASK 0xF struct voxel { blockid_t id;