diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 3eb6fe86..378dc4e7 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -27,6 +27,8 @@ BlocksRenderer::BlocksRenderer( const ContentGfxCache* cache, const EngineSettings* settings ) : content(content), + vertexBuffer(std::make_unique(capacity)), + indexBuffer(std::make_unique(capacity)), vertexOffset(0), indexOffset(0), indexSize(0), @@ -34,8 +36,6 @@ BlocksRenderer::BlocksRenderer( cache(cache), settings(settings) { - vertexBuffer = std::make_unique(capacity); - indexBuffer = std::make_unique(capacity); voxelsBuffer = std::make_unique( CHUNK_W + voxelBufferPadding*2, CHUNK_H, @@ -60,10 +60,10 @@ void BlocksRenderer::vertex(const vec3& coord, float u, float v, const vec4& lig uint32_t integer; } compressed; - compressed.integer = (uint32_t(light.r * 255) & 0xff) << 24; - compressed.integer |= (uint32_t(light.g * 255) & 0xff) << 16; - compressed.integer |= (uint32_t(light.b * 255) & 0xff) << 8; - compressed.integer |= (uint32_t(light.a * 255) & 0xff); + compressed.integer = (static_cast(light.r * 255) & 0xff) << 24; + compressed.integer |= (static_cast(light.g * 255) & 0xff) << 16; + compressed.integer |= (static_cast(light.b * 255) & 0xff) << 8; + compressed.integer |= (static_cast(light.a * 255) & 0xff); vertexBuffer[vertexOffset++] = compressed.floating; } @@ -78,15 +78,17 @@ void BlocksRenderer::index(int a, int b, int c, int d, int e, int f) { indexOffset += 4; } -/* Add face with precalculated lights */ -void BlocksRenderer::face(const vec3& coord, - float w, float h, float d, - const vec3& axisX, - const vec3& axisY, - const vec3& axisZ, - const UVRegion& region, - const vec4(&lights)[4], - const vec4& tint) { +/// @brief Add face with precalculated lights +void BlocksRenderer::face( + const vec3& coord, + float w, float h, float d, + const vec3& axisX, + const vec3& axisY, + const vec3& axisZ, + const UVRegion& region, + const vec4(&lights)[4], + const vec4& tint +) { if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { overflow = true; return; @@ -102,23 +104,27 @@ void BlocksRenderer::face(const vec3& coord, index(0, 1, 3, 1, 2, 3); } -void BlocksRenderer::vertex(const vec3& coord, - float u, float v, - const vec4& tint, - const vec3& axisX, - const vec3& axisY, - const vec3& axisZ) { +void BlocksRenderer::vertex( + const vec3& coord, + float u, float v, + const vec4& tint, + const vec3& axisX, + const vec3& axisY, + const vec3& axisZ +) { vec3 pos = coord+axisZ*0.5f+(axisX+axisY)*0.5f; vec4 light = pickSoftLight(ivec3(round(pos.x), round(pos.y), round(pos.z)), axisX, axisY); vertex(coord, u, v, light * tint); } -void BlocksRenderer::face(const vec3& coord, - const vec3& X, - const vec3& Y, - const vec3& Z, - const UVRegion& region, - bool lights) { +void BlocksRenderer::face( + const vec3& coord, + const vec3& X, + const vec3& Y, + const vec3& Z, + const UVRegion& region, + bool lights +) { if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { overflow = true; return; @@ -148,14 +154,13 @@ void BlocksRenderer::face(const vec3& coord, index(0, 1, 2, 0, 2, 3); } -void BlocksRenderer::tetragonicFace(const vec3& coord, const vec3& p1, - const vec3& p2, const vec3& p3, const vec3& p4, - const vec3& X, - const vec3& Y, - const vec3& Z, - const UVRegion& texreg, - bool lights) { - +void BlocksRenderer::tetragonicFace( + const vec3& coord, + const vec3& p1, const vec3& p2, const vec3& p3, const vec3& p4, + const vec3& X, const vec3& Y, const vec3& Z, + const UVRegion& texreg, + bool lights +) { const vec3 fp1 = (p1.x - 0.5f) * X + (p1.y - 0.5f) * Y + (p1.z - 0.5f) * Z; const vec3 fp2 = (p2.x - 0.5f) * X + (p2.y - 0.5f) * Y + (p2.z - 0.5f) * Z; const vec3 fp3 = (p3.x - 0.5f) * X + (p3.y - 0.5f) * Y + (p3.z - 0.5f) * Z; @@ -182,17 +187,19 @@ void BlocksRenderer::tetragonicFace(const vec3& coord, const vec3& p1, index(0, 1, 3, 1, 2, 3); } -void BlocksRenderer::blockXSprite(int x, int y, int z, - const vec3& size, - const UVRegion& texface1, - const UVRegion& texface2, - float spread) { - vec4 lights[]{ - pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}), - pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), - pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), - pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}) }; - +void BlocksRenderer::blockXSprite( + int x, int y, int z, + const vec3& size, + const UVRegion& texface1, + const UVRegion& texface2, + float spread +) { + vec4 lights[] { + pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}), + pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), + pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), + pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}) + }; int rand = ((x * z + y) ^ (z * y - x)) * (z + y); float xs = ((float)(char)rand / 512) * spread; @@ -218,7 +225,7 @@ void BlocksRenderer::blockXSprite(int x, int y, int z, // HINT: texture faces order: {east, west, bottom, top, south, north} -/* AABB blocks render method */ +/// @brief AABB blocks render method void BlocksRenderer::blockAABB( const ivec3& icoord, const UVRegion(&texfaces)[6], @@ -259,8 +266,9 @@ void BlocksRenderer::blockAABB( face(coord, Z*size.z, Y*size.y, -X*size.x, texfaces[0], lights); // east } -void BlocksRenderer::blockCustomModel(const ivec3& icoord, - const Block* block, ubyte rotation, bool lights) { +void BlocksRenderer::blockCustomModel( + const ivec3& icoord, const Block* block, ubyte rotation, bool lights +) { vec3 X(1, 0, 0); vec3 Y(0, 1, 0); vec3 Z(0, 0, 1); @@ -347,8 +355,9 @@ bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const { blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); - if (id == BLOCK_VOID) + if (id == BLOCK_VOID) { return false; + } const Block& block = *blockDefsCache[id]; if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) { return true; @@ -360,8 +369,9 @@ bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); - if (id == BLOCK_VOID) + if (id == BLOCK_VOID) { return false; + } const Block& block = *blockDefsCache[id]; if (block.lightPassing) { return true; @@ -371,15 +381,13 @@ bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { vec4 BlocksRenderer::pickLight(int x, int y, int z) const { if (isOpenForLight(x, y, z)) { - light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x, - y, + light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); return vec4(Lightmap::extract(light, 0) / 15.0f, - Lightmap::extract(light, 1) / 15.0f, - Lightmap::extract(light, 2) / 15.0f, - Lightmap::extract(light, 3) / 15.0f); - } - else { + Lightmap::extract(light, 1) / 15.0f, + Lightmap::extract(light, 2) / 15.0f, + Lightmap::extract(light, 3) / 15.0f); + } else { return vec4(0.0f); } } @@ -391,17 +399,20 @@ vec4 BlocksRenderer::pickLight(const ivec3& coord) const { vec4 BlocksRenderer::pickSoftLight(const ivec3& coord, const ivec3& right, const ivec3& up) const { - return ( - pickLight(coord) + - pickLight(coord - right) + - pickLight(coord - right - up) + - pickLight(coord - up)) * 0.25f; + return (pickLight(coord) + + pickLight(coord - right) + + pickLight(coord - right - up) + + pickLight(coord - up)) * 0.25f; } vec4 BlocksRenderer::pickSoftLight(float x, float y, float z, - const ivec3& right, - const ivec3& up) const { - return pickSoftLight({int(round(x)), int(round(y)), int(round(z))}, right, up); + const ivec3& right, + const ivec3& up) const { + return pickSoftLight({ + static_cast(round(x)), + static_cast(round(y)), + static_cast(round(z))}, + right, up); } void BlocksRenderer::render(const voxel* voxels) { @@ -457,10 +468,8 @@ void BlocksRenderer::render(const voxel* voxels) { void BlocksRenderer::build(const Chunk* chunk, const ChunksStorage* chunks) { this->chunk = chunk; voxelsBuffer->setPosition( - chunk->x * CHUNK_W - voxelBufferPadding, - 0, - chunk->z * CHUNK_D - voxelBufferPadding - ); + chunk->x * CHUNK_W - voxelBufferPadding, 0, + chunk->z * CHUNK_D - voxelBufferPadding); chunks->getVoxels(voxelsBuffer.get(), settings->graphics.backlight.get()); overflow = false; vertexOffset = 0; diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 5d5676c0..2384d7c2 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -293,7 +293,7 @@ void PlayerController::updateControls(float delta){ player->updateInput(level, input, delta); } -static int determine_rotation(Block* def, glm::ivec3& norm, glm::vec3& camDir) { +static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& camDir) { if (def && def->rotatable){ const std::string& name = def->rotations.name; if (name == "pipe") { diff --git a/src/maths/aabb.hpp b/src/maths/aabb.hpp index 49177113..40f57ccc 100644 --- a/src/maths/aabb.hpp +++ b/src/maths/aabb.hpp @@ -3,7 +3,7 @@ #include -// Axis Aligned Bounding Box +/// @brief Axis Aligned Bounding Box struct AABB { glm::vec3 a {0.0f}; glm::vec3 b {1.0f}; @@ -13,17 +13,17 @@ struct AABB { AABB(glm::vec3 size) : a(0.0f), b(size) { } - /* Get AABB point with minimal x,y,z */ + /// @brief Get AABB point with minimal x,y,z inline glm::vec3 min() const { return glm::min(a, b); } - /* Get AABB point with minimal x,y,z */ + /// @brief Get AABB point with minimal x,y,z inline glm::vec3 max() const { return glm::max(a, b); } - /* Get AABB dimensions: width, height, depth */ + /// @brief Get AABB dimensions: width, height, depth inline glm::vec3 size() const { return glm::vec3( fabs(b.x - a.x), @@ -36,14 +36,14 @@ struct AABB { return (a + b) * 0.5f; } - /* Multiply AABB size from center */ + /// @brief Multiply AABB size from center inline void scale(const glm::vec3 mul) { glm::vec3 center = (a + b) * 0.5f; a = (a - center) * mul + center; b = (b - center) * mul + center; } - /* Multiply AABB size from given origin */ + /// @brief Multiply AABB size from given origin inline void scale(const glm::vec3 mul, const glm::vec3 orig) { glm::vec3 beg = min(); glm::vec3 end = max(); @@ -52,7 +52,7 @@ struct AABB { b = (b - center) * mul + center; } - /* Check if given point is inside */ + /// @brief Check if given point is inside inline bool contains(const glm::vec3 pos) const { const glm::vec3 p = min(); const glm::vec3 s = size(); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index b4107832..1a3d6bd1 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -323,9 +323,9 @@ voxel* Chunks::rayCast( end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; - iend.x = ix; - iend.y = iy; - iend.z = iz; + iend.x = ix; + iend.y = iy; + iend.z = iz; if (!def->rt.solid) { const std::vector& hitboxes = def->rotatable @@ -337,7 +337,14 @@ voxel* Chunks::rayCast( bool hit = false; - for (const auto& box : hitboxes) { + glm::vec3 offset {}; + if (voxel->state.segment) { + offset = seekOrigin(iend, def, voxel->state) - iend; + } + + for (auto box : hitboxes) { + box.a += offset; + box.b += offset; scalar_t boxDistance; glm::ivec3 boxNorm; if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None && boxDistance < distance) { @@ -446,9 +453,14 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis glm::ivec3 norm; Ray ray(start, dir); + glm::ivec3 offset {}; + if (voxel->state.segment) { + offset = seekOrigin({ix, iy, iz}, def, voxel->state) - glm::ivec3(ix, iy, iz); + } + for (const auto& box : hitboxes) { // norm is dummy now, can be inefficient - if (ray.intersectAABB(glm::ivec3(ix, iy, iz), box, maxDist, norm, distance) > RayRelation::None) { + if (ray.intersectAABB(glm::ivec3(ix, iy, iz)+offset, box, maxDist, norm, distance) > RayRelation::None) { return start + (dir * glm::vec3(distance)); } }