From 0c764bcbd9fc16d18d62b03835ffeb064f8bf6b9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 4 Dec 2023 15:52:09 +0300 Subject: [PATCH] AABB blocks rotation support (WIP part 1) --- res/content/base/blocks/pane.json | 7 +- src/frontend/WorldRenderer.cpp | 7 +- src/graphics/BlocksRenderer.cpp | 141 ++++++++++++++---------------- src/graphics/BlocksRenderer.h | 25 ++++-- src/logic/PlayerController.cpp | 4 + src/logic/PlayerController.h | 1 + src/voxels/Block.cpp | 20 ++++- src/voxels/Block.h | 5 +- 8 files changed, 120 insertions(+), 90 deletions(-) diff --git a/res/content/base/blocks/pane.json b/res/content/base/blocks/pane.json index 28d684b4..1ceed9b8 100644 --- a/res/content/base/blocks/pane.json +++ b/res/content/base/blocks/pane.json @@ -8,7 +8,8 @@ "pane" ], "model": "aabb", - "hitbox": [0.0, 0.0, 0.0, 1.0, 1.0, 0.1], + "hitbox": [0.0, 0.2, 0.0, 1.0, 1.0, 0.1], "light-passing": true, - "sky-light-passing": true -} \ No newline at end of file + "sky-light-passing": true, + "rotation": "pipe" +} diff --git a/src/frontend/WorldRenderer.cpp b/src/frontend/WorldRenderer.cpp index 2afa059b..c562f8a4 100644 --- a/src/frontend/WorldRenderer.cpp +++ b/src/frontend/WorldRenderer.cpp @@ -193,7 +193,12 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera){ const vec3 pos = PlayerController::selectedBlockPosition; const vec3 point = PlayerController::selectedPointPosition; const vec3 norm = PlayerController::selectedBlockNormal; - const AABB& hitbox = block->hitbox; + AABB hitbox = block->hitbox; + if (block->rotatable) { + auto states = PlayerController::selectedBlockStates; + block->rotations.variants[states].transform(hitbox); + } + const vec3 center = pos + hitbox.center(); const vec3 size = hitbox.size(); linesShader->use(); diff --git a/src/graphics/BlocksRenderer.cpp b/src/graphics/BlocksRenderer.cpp index bfd52bb6..7e62fc6a 100644 --- a/src/graphics/BlocksRenderer.cpp +++ b/src/graphics/BlocksRenderer.cpp @@ -92,33 +92,6 @@ void BlocksRenderer::face(const vec3& coord, float w, float h, index(0, 1, 3, 1, 2, 3); } -void BlocksRenderer::face(const vec3& coord, float w, float h, - const vec3& axisX, - const vec3& axisY, - const UVRegion& region, - const vec4(&lights)[4], - const vec4& tint, - bool rotated) { - if (vertexOffset + VERTEX_SIZE * 4 > capacity) { - overflow = true; - return; - } - if (rotated) { - vertex(coord, region.u2, region.v1, lights[0] * tint); - vertex(coord + axisX * w, region.u2, region.v2, lights[1] * tint); - vertex(coord + axisX * w + axisY * h, region.u1, region.v2, lights[2] * tint); - vertex(coord + axisY * h, region.u1, region.v1, lights[3] * tint); - index(0, 1, 2, 0, 2, 3); - } - else { - vertex(coord, region.u1, region.v1, lights[0] * tint); - vertex(coord + axisX * w, region.u2, region.v1, lights[1] * tint); - vertex(coord + axisX * w + axisY * h, region.u2, region.v2, lights[2] * tint); - vertex(coord + axisY * h, region.u1, region.v2, lights[3] * tint); - index(0, 1, 2, 0, 2, 3); - } -} - void BlocksRenderer::vertex(const ivec3& coord, float u, float v, const vec4& tint, const ivec3& axisX, @@ -128,6 +101,15 @@ void BlocksRenderer::vertex(const ivec3& coord, float u, float v, vertex(coord, u, v, light * tint); } +void BlocksRenderer::vertex(const vec3& coord, float u, float v, + const vec4& tint, + const ivec3& axisX, + const ivec3& axisY, + const ivec3& axisZ) { + vec4 light = pickSoftLight(ivec3(coord.x, coord.y, coord.z)+axisZ, axisX, axisY); + vertex(coord, u, v, light * tint); +} + void BlocksRenderer::face(const ivec3& coord, const ivec3& axisX, const ivec3& axisY, @@ -152,6 +134,35 @@ void BlocksRenderer::face(const ivec3& coord, index(0, 1, 2, 0, 2, 3); } +void BlocksRenderer::face(const ivec3& coord_, + const ivec3& axisX, + const ivec3& axisY, + const ivec3& axisZ, + const ivec3& laxisZ, + const vec3& offset, + float width, + float height, + float depth, + const UVRegion& region) { + if (vertexOffset + VERTEX_SIZE * 4 > capacity) { + overflow = true; + return; + } + + const vec3 sunVector = vec3(0.431934f, 0.863868f, 0.259161f); + float d = glm::dot(vec3(axisZ.x, axisZ.y, axisZ.z), sunVector); + d = 0.75f + d*0.25f; + + vec4 tint(d); + vec3 coord(vec3(coord_) + offset); + + vertex(coord + vec3(axisZ)*depth, region.u1, region.v1, tint, axisX, axisY, laxisZ); + vertex(coord + vec3(axisZ)*depth + vec3(axisX)*width, region.u2, region.v1, tint, axisX, axisY, laxisZ); + vertex(coord + vec3(axisZ)*depth + vec3(axisX)*width + vec3(axisY)*height, region.u2, region.v2, tint, axisX, axisY, laxisZ); + vertex(coord + vec3(axisZ)*depth + vec3(axisY)*height, region.u1, region.v2, tint, axisX, axisY, laxisZ); + index(0, 1, 2, 0, 2, 3); +} + void BlocksRenderer::cube(const vec3& coord, const vec3& size, const UVRegion(&texfaces)[6]) { vec4 lights[]{ vec4(),vec4(),vec4(),vec4() }; @@ -220,57 +231,41 @@ void BlocksRenderer::blockXSprite(int x, int y, int z, const vec3& size, const U } void BlocksRenderer::blockCubeShaded(const vec3& pos, const vec3& size, const UVRegion(&texfaces)[6], const Block* block, ubyte states) { - int rot = 0; float x = pos.x; float y = pos.y; float z = pos.z; - { - vec4 lights[]{ - pickSoftLight(x, y, z + 1, {1, 0, 0}, {0, 1, 0}), - pickSoftLight(x + 1, y, z + 1, {1, 0, 0}, {0, 1, 0}), - pickSoftLight(x + 1, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}), - pickSoftLight(x, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}) }; - face(vec3(x, y, z), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], lights, vec4(0.9f), rot == 1); - } { - vec4 lights[]{ - pickSoftLight(pos.x, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}), - pickSoftLight(pos.x - 1, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}), - pickSoftLight(pos.x - 1, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}), - pickSoftLight(pos.x, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}) }; - face(vec3(x + size.x, y, z - size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], lights, vec4(0.75f), rot == 1); - } { - vec4 lights[]{ - pickSoftLight(x, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}), - pickSoftLight(x + 1, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}), - pickSoftLight(x + 1, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}), - pickSoftLight(x, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}) }; - face(vec3(x, y + size.y, z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], lights, vec4(1.0f), rot == 1); - } { - vec4 lights[]{ - pickSoftLight(pos.x, pos.y - 1, pos.z - 1, {1, 0, 0}, {0, 0, -1}), - pickSoftLight(pos.x + 1, y - 1, pos.z - 1, {1, 0, 0}, {0, 0,-1}), - pickSoftLight(pos.x + 1, y - 1, pos.z, {1, 0, 0}, {0, 0, -1}), - pickSoftLight(x, y - 1, z, {1, 0, 0}, {0, 0, -1}) }; - face(vec3(x, y, z - size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], lights, vec4(0.6f), rot == 1); - } { - vec4 lights[]{ - pickSoftLight(x - 1, y, z - 1, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x - 1, y, z, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x - 1, y + 1, z, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x - 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}) }; - face(vec3(x, y, z - size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], lights, vec4(0.7f), rot == 3); - } { - vec4 lights[]{ - pickSoftLight(x + 1, y, z, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x + 1, y, z - 1, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x + 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}), - pickSoftLight(x + 1, y + 1, z, {0, 0, -1}, {0, 1, 0}) }; - face(vec3(x + size.x, y, z), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], lights, vec4(0.8f), rot == 3); + ivec3 X(1, 0, 0); + ivec3 Y(0, 1, 0); + ivec3 Z(0, 0, 1); + ivec3 loff(0); + ivec3 coord(x, y, z); + if (block->rotatable) { + 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; } + + vec3 local = pos - vec3(coord); + local -= loff; + face(coord, X, Y, Z, Z+loff, local, size.x, size.y, -size.z, texfaces[5]); + face(coord+X-Z, -X, Y, -Z, Z-Z-X+loff, local, size.x, size.y, 0.0f, texfaces[4]); + + face(coord+Y, X, -Z, Y, Y-Y+loff, local-vec3(Z)*size.z, size.x, size.z, 0.0f, texfaces[3]); + face(coord-Z, X, Z, -Y, -Y+Z+loff, local, size.x, size.z, 0.0f, texfaces[2]); + + face(coord+X, -Z, Y, X, X-X+loff, local-vec3(Z)*size.z, size.z, size.y, 0.0f, texfaces[1]); + face(coord-Z, Z, Y, -X, -X+Z+loff, local, size.z, size.y, 0.0f, texfaces[0]); } -void BlocksRenderer::blockCubeShaded(int x, int y, int z, const UVRegion(&texfaces)[6], const Block* block, ubyte states) { +void BlocksRenderer::blockCubeShaded(int x, int y, int z, + const UVRegion(&texfaces)[6], + const Block* block, + ubyte states) { ubyte group = block->drawGroup; ivec3 X(1, 0, 0); @@ -394,8 +389,8 @@ void BlocksRenderer::render(const voxel* voxels, int atlas_size) { case BlockModel::aabb: { vec3 size = def.hitbox.size(); vec3 off = def.hitbox.min(); - off.z *= -1.0f; - off.z = -1.0f-off.z + size.z; + //off.z *= -1.0f; + //off.z = -1.0f-off.z + size.z; blockCubeShaded(off+vec3(x,y,z), size, texfaces, &def, vox.states); break; } diff --git a/src/graphics/BlocksRenderer.h b/src/graphics/BlocksRenderer.h index a805d4a6..f58c56c8 100644 --- a/src/graphics/BlocksRenderer.h +++ b/src/graphics/BlocksRenderer.h @@ -43,20 +43,18 @@ class BlocksRenderer { const glm::ivec3& axisY, const glm::ivec3& axisZ); - void face(const glm::vec3& coord, float w, float h, - const glm::vec3& axisX, - const glm::vec3& axisY, - const UVRegion& region, - const glm::vec4(&lights)[4], - const glm::vec4& tint); + void vertex(const glm::vec3& coord, float u, float v, + const glm::vec4& brightness, + const glm::ivec3& axisX, + const glm::ivec3& axisY, + const glm::ivec3& axisZ); void face(const glm::vec3& coord, float w, float h, const glm::vec3& axisX, const glm::vec3& axisY, const UVRegion& region, const glm::vec4(&lights)[4], - const glm::vec4& tint, - bool rotated); + const glm::vec4& tint); void face(const glm::ivec3& coord, const glm::ivec3& axisX, @@ -65,6 +63,17 @@ class BlocksRenderer { const glm::ivec3& laxisZ, const UVRegion& region); + void face(const glm::ivec3& coord, + const glm::ivec3& axisX, + const glm::ivec3& axisY, + const glm::ivec3& axisZ, + const glm::ivec3& laxisZ, + const glm::vec3& offset, + float width, + float height, + float depth, + const UVRegion& region); + void face(const glm::vec3& coord, float w, float h, const glm::vec3& axisX, const glm::vec3& axisY, diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 5bca9899..c1bb1306 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -110,6 +110,7 @@ vec3 PlayerController::selectedBlockPosition; vec3 PlayerController::selectedPointPosition; vec3 PlayerController::selectedBlockNormal; int PlayerController::selectedBlockId = -1; +int PlayerController::selectedBlockStates = 0; PlayerController::PlayerController(Level* level, const EngineSettings& settings) : level(level), @@ -133,6 +134,7 @@ void PlayerController::update(float delta, bool input, bool pause) { updateInteraction(); } else { selectedBlockId = -1; + selectedBlockStates = 0; } } @@ -207,6 +209,7 @@ void PlayerController::updateInteraction(){ if (vox != nullptr){ player->selectedVoxel = *vox; selectedBlockId = vox->id; + selectedBlockStates = vox->states; selectedBlockPosition = iend; selectedPointPosition = end; selectedBlockNormal = norm; @@ -250,5 +253,6 @@ void PlayerController::updateInteraction(){ } } else { selectedBlockId = -1; + selectedBlockStates = 0; } } \ No newline at end of file diff --git a/src/logic/PlayerController.h b/src/logic/PlayerController.h index e9e029fd..a2f7ccf9 100644 --- a/src/logic/PlayerController.h +++ b/src/logic/PlayerController.h @@ -40,6 +40,7 @@ public: static glm::vec3 selectedBlockNormal; static glm::vec3 selectedPointPosition; static int selectedBlockId; + static int selectedBlockStates; PlayerController(Level* level, const EngineSettings& settings); void update(float delta, bool input, bool pause); diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 41602a26..085646ed 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -1,12 +1,24 @@ #include "Block.h" -BlockRotProfile BlockRotProfile::PIPE {{ +using glm::vec3; + +void CoordSystem::transform(AABB& aabb) { + vec3 X(axisX); + vec3 Y(axisY); + vec3 Z(axisZ); + aabb.a = X * aabb.a.x + Y * aabb.a.y + Z * aabb.a.z; + aabb.b = X * aabb.b.x + Y * aabb.b.y + Z * aabb.b.z; + aabb.a += fix2; + aabb.b += fix2; +} + +const BlockRotProfile BlockRotProfile::PIPE {{ // Vertical - {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}}, + {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}, {0, 0, 0}}, // X-Aligned - {{0, -1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}}, + {{0, -1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 0}}, // Z-Aligned - {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}, {0, 0, -1}}, + {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}, {0, 0, -1}, {0, 1, 0}}, }}; Block::Block(std::string name) diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 42fdf0cc..7d8ebc58 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -22,6 +22,9 @@ struct CoordSystem { glm::ivec3 axisZ; // Grid 3d position fix offset (for negative vectors) glm::ivec3 fix; + glm::ivec3 fix2; + + void transform(AABB& aabb); }; struct BlockRotProfile { @@ -30,7 +33,7 @@ struct BlockRotProfile { /* Wood logs, pillars, pipes 3 orientations supported */ - static BlockRotProfile PIPE; + static const BlockRotProfile PIPE; }; enum class BlockModel {