From 42e632d220d2a8e102f1c5f94c4741a714c8f065 Mon Sep 17 00:00:00 2001 From: Ara Date: Fri, 8 Dec 2023 09:53:51 +0600 Subject: [PATCH 1/5] ScopeTimer + small fixes --- .gitignore | 1 + src/frontend/gui/panels.h | 3 ++- src/util/timeutil.cpp | 8 ++++++++ src/util/timeutil.h | 13 +++++++++++++ src/voxels/Chunks.cpp | 11 +++++------ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 1dfd2a2a3..55057c5a2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ Debug/src/**/*.o Debug/voxel_engine /build +/screenshots /world /worlds/**/* diff --git a/src/frontend/gui/panels.h b/src/frontend/gui/panels.h index 3524576fe..1911abfc6 100644 --- a/src/frontend/gui/panels.h +++ b/src/frontend/gui/panels.h @@ -93,7 +93,8 @@ namespace gui { void back(); void clearHistory(); void reset(); - +//comment or erase pragma if you hate notes.. +#pragma message("gui::PagesControl::current() returns Page by-value! (can initiate unexpected behaviour)") Page current(); }; } diff --git a/src/util/timeutil.cpp b/src/util/timeutil.cpp index 7cee8e9f8..04be381f5 100644 --- a/src/util/timeutil.cpp +++ b/src/util/timeutil.cpp @@ -1,5 +1,7 @@ #include "timeutil.h" +#include + using std::chrono::high_resolution_clock; using std::chrono::duration_cast; using std::chrono::microseconds; @@ -11,6 +13,12 @@ int64_t timeutil::Timer::stop() { return duration_cast(high_resolution_clock::now()-start).count(); } +timeutil::ScopeLogTimer::ScopeLogTimer(long long id) : scopeid_(id) {} + +timeutil::ScopeLogTimer::~ScopeLogTimer() { + std::cout << "Scope "<< scopeid_ <<" finished in "<< ScopeLogTimer::stop() << " micros."<setModified(true); } - +#include "../util/timeutil.h" voxel* Chunks::rayCast(vec3 start, vec3 dir, float maxDist, @@ -218,6 +218,7 @@ voxel* Chunks::rayCast(vec3 start, voxel* voxel = get(ix, iy, iz); const Block* def = nullptr; if (voxel == nullptr || (def = contentIds->getBlockDef(voxel->id))->selectable){ + timeutil::ScopeLogTimer lg((long long)def); end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; @@ -336,7 +337,7 @@ void Chunks::translate(int dx, int dz){ } for (int z = 0; z < d; z++){ for (int x = 0; x < w; x++){ - shared_ptr chunk = chunks[z * d + x]; + shared_ptr chunk = chunks[z * w + x]; int nx = x - dx; int nz = z - dz; if (chunk == nullptr) @@ -351,9 +352,7 @@ void Chunks::translate(int dx, int dz){ chunksSecond[nz * w + nx] = chunk; } } - shared_ptr* ctemp = chunks; - chunks = chunksSecond; - chunksSecond = ctemp; + std::swap(chunks, chunksSecond); ox += dx; oz += dz; From ed57c0b07583a2404d3072a5ff7a03a918527579 Mon Sep 17 00:00:00 2001 From: Ara Date: Sat, 9 Dec 2023 18:47:25 +0600 Subject: [PATCH 2/5] raycast impl (not finished normals and intersection point returning) --- src/maths/rays.cpp | 333 ++++++++++++++++++++++++++++++++++++++++++ src/maths/rays.h | 81 ++++++++++ src/voxels/Chunks.cpp | 37 +++-- 3 files changed, 441 insertions(+), 10 deletions(-) create mode 100644 src/maths/rays.cpp create mode 100644 src/maths/rays.h diff --git a/src/maths/rays.cpp b/src/maths/rays.cpp new file mode 100644 index 000000000..711c660fb --- /dev/null +++ b/src/maths/rays.cpp @@ -0,0 +1,333 @@ + +#include "rays.h" +#include "aabb.h" + +#include "glm/glm.hpp" + +constexpr std::array AABBFACES_KINDS_ORDER = { + AAFaceKind::Xperp, AAFaceKind::Xperp, + AAFaceKind::Yperp, AAFaceKind::Yperp, + AAFaceKind::Zperp, AAFaceKind::Zperp}; +std::unordered_map Rays::raysBoxCache_ = {}; +const rayvec3 X_AXIS = rayvec3(1,0,0), Y_AXIS = rayvec3(0,1,0), Z_AXIS = rayvec3(0,0,1); + +//make edges from AABB +AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){ + rayvec3 pbMin = parentBox.min(), + pbMax = parentBox.max(), + pbRealPos = parentBoxPos + pbMin; + rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ), + xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ), + xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y ); + faces[0] = {pbRealPos, yzMax}; + + faces[1] = {parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax}; + + faces[2] = {pbRealPos, xzMax}; + + faces[3] = {parentBoxPos + rayvec3(pbMin.x, pbMax.y, pbMin.z), xzMax}; + + faces[4] = {pbRealPos, xyMax}; + + faces[5] = {parentBoxPos + rayvec3(pbMin.x, pbMin.y, pbMax.z), xyMax}; +} + +template <> +RayRelation Rays::rayIntersectAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner, //y and z global coords of opposite corner + rayvec3& intersectPoint_ret + ){ + if (fabs(glm::dot(rayDir, X_AXIS)) < 1.0E-8){ //precision + if (rayOrigin.x == faceMin.x) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.x - rayOrigin.x) / (rayDir.x); + intersectPoint_ret = {faceMin.x, + rayCoef*rayDir.y + rayOrigin.y, + rayCoef*rayDir.z + rayOrigin.z}; + + if (rayDir.x > 0){ + if (intersectPoint_ret.y >= faceMin.y + && intersectPoint_ret.y <= faceOppositeCorner[0] + && intersectPoint_ret.z >= faceMin.z + && intersectPoint_ret.z <= faceOppositeCorner[1]){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPoint_ret.y <= faceMin.y + && intersectPoint_ret.y >= faceOppositeCorner[0] + && intersectPoint_ret.z <= faceMin.z + && intersectPoint_ret.z >= faceOppositeCorner[1]){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +template <> +RayRelation Rays::rayIntersectAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner, //x and z global coords of opposite corner + rayvec3& intersectPoint_ret + ){ + if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision + if (rayOrigin.y == faceMin.y) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.y - rayOrigin.y) / (rayDir.y); + intersectPoint_ret = {rayCoef*rayDir.x + rayOrigin.x, + faceMin.y, + rayCoef*rayDir.z + rayOrigin.z}; + + if (rayDir.y > 0){ + if (intersectPoint_ret.x >= faceMin.x //Face-hit check + && intersectPoint_ret.x <= faceOppositeCorner[0] + && intersectPoint_ret.z >= faceMin.z + && intersectPoint_ret.z <= faceOppositeCorner[1] ){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPoint_ret.x <= faceMin.x //Face-hit check for negative dir. + && intersectPoint_ret.x >= faceOppositeCorner[0] + && intersectPoint_ret.z <= faceMin.z + && intersectPoint_ret.z >= faceOppositeCorner[1]){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +template <> +RayRelation Rays::rayIntersectAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner, //x and y global coords of opposite corner + rayvec3& intersectPoint_ret + ){ + if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision + if (rayOrigin.z == faceMin.z) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.z - rayOrigin.z) / (rayDir.z); + intersectPoint_ret = {rayCoef*rayDir.x + rayOrigin.x, + rayCoef*rayDir.y + rayOrigin.y, + faceMin.z}; + + if (rayDir.y > 0){ + if (intersectPoint_ret.x >= faceMin.x //Face-hit check + && intersectPoint_ret.x <= faceOppositeCorner[0] + && intersectPoint_ret.y >= faceMin.y + && intersectPoint_ret.y <= faceOppositeCorner[1] ){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPoint_ret.x <= faceMin.x //Face-hit check + && intersectPoint_ret.x >= faceOppositeCorner[0] + && intersectPoint_ret.y <= faceMin.y + && intersectPoint_ret.y >= faceOppositeCorner[1] ){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +template <> +RayRelation Rays::isRayIntersectsAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner + ){ + if (fabs(glm::dot(rayDir, X_AXIS)) < 1.0E-8){ //precision of "parallelity" + if (rayOrigin.x == faceMin.x) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.x - rayOrigin.x); + rayvec3 intersectPointMult = {faceMin.x * rayDir.x, + rayCoef*rayDir.y + rayOrigin.y * rayDir.x, + rayCoef*rayDir.z + rayOrigin.z * rayDir.x}; + + if (rayDir.x > 0){ + if (intersectPointMult.y >= faceMin.y * rayDir.x //Face-hit check + && intersectPointMult.y <= faceOppositeCorner[0] * rayDir.x + && intersectPointMult.z >= faceMin.z * rayDir.x + && intersectPointMult.z <= faceOppositeCorner[1] * rayDir.x){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPointMult.y <= faceMin.y * rayDir.x //Face-hit check for negative dir. + && intersectPointMult.y >= faceOppositeCorner[0] * rayDir.x + && intersectPointMult.z <= faceMin.z * rayDir.x + && intersectPointMult.z >= faceOppositeCorner[1] * rayDir.x){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +template <> +RayRelation Rays::isRayIntersectsAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner + ){ + if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision + if (rayOrigin.y == faceMin.y) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.y - rayOrigin.y); + rayvec3 intersectPointMult = {rayCoef*rayDir.x + rayOrigin.x * rayDir.y, + faceMin.y * rayDir.y, + rayCoef*rayDir.z + rayOrigin.z * rayDir.y}; + + if (rayDir.y > 0){ + if (intersectPointMult.x >= faceMin.x * rayDir.y //Face-hit check + && intersectPointMult.x <= faceOppositeCorner[0] * rayDir.y + && intersectPointMult.z >= faceMin.z * rayDir.y + && intersectPointMult.z <= faceOppositeCorner[1] * rayDir.y){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPointMult.x <= faceMin.x * rayDir.y //Face-hit check for negative dir. + && intersectPointMult.x >= faceOppositeCorner[0] * rayDir.y + && intersectPointMult.z <= faceMin.z * rayDir.y + && intersectPointMult.z >= faceOppositeCorner[1] * rayDir.y){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +template <> +RayRelation Rays::isRayIntersectsAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner + ){ + if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision + if (rayOrigin.z == faceMin.z) { + return RayRelation::Embed; // there can be check of hit, but not necessarily + } + return RayRelation::Parallel; + } + + glm::float64 rayCoef = (faceMin.z - rayOrigin.z); + rayvec3 intersectPointMult = {rayCoef*rayDir.x + rayOrigin.x * rayDir.z, + rayCoef*rayDir.y + rayOrigin.y * rayDir.z, + faceMin.z * rayDir.z}; + + if (rayDir.y > 0){ + if (intersectPointMult.x >= faceMin.x * rayDir.z //Face-hit check + && intersectPointMult.x <= faceOppositeCorner[0] * rayDir.z + && intersectPointMult.y >= faceMin.y * rayDir.z + && intersectPointMult.y <= faceOppositeCorner[1] * rayDir.z){ + return RayRelation::Intersect; + } + } + else{ + if (intersectPointMult.x <= faceMin.x * rayDir.z //Face-hit check + && intersectPointMult.x >= faceOppositeCorner[0] * rayDir.z + && intersectPointMult.y <= faceMin.y * rayDir.z + && intersectPointMult.y >= faceOppositeCorner[1] * rayDir.z){ + return RayRelation::Intersect; + } + } + return RayRelation::None; +} + +RayRelation Rays::rayIntersectAABB( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& boxPos, + const AABB& box, + rayvec3& pointIn_ret, + rayvec3& pointOut_ret, + glm::ivec3& normal_ret){ + if constexpr (IS_RAYS_BOX_CACHE_ON){ + + if (raysBoxCache_.find(boxPos) != raysBoxCache_.end()){ + const AABBFaces& boxFaces = raysBoxCache_[boxPos]; + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + } else { + const AABBFaces& boxFaces = AABBFaces(boxPos, box); + raysBoxCache_[boxPos] = boxFaces; + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + } + + } else { + const AABBFaces& boxFaces = AABBFaces(boxPos, box); + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + } + +} + +RayRelation Rays::rayIntersectAABBFaces( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const AABBFaces& boxFaces, + rayvec3& pointIn_ret, + rayvec3& pointOut_ret, + glm::ivec3& normal_ret){//TODO: refs update + RayRelation rel; + unsigned char intersectedCount = 0; + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[0].first, boxFaces.faces[0].second + ); + intersectedCount+= (bool)rel; + + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[1].first, boxFaces.faces[1].second + ); + intersectedCount+= (bool)rel; + + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[2].first, boxFaces.faces[2].second + ); + intersectedCount+= (bool)rel; + + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[3].first, boxFaces.faces[3].second + ); + intersectedCount+= (bool)rel; + + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[4].first, boxFaces.faces[4].second + ); + intersectedCount+= (bool)rel; + + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[5].first, boxFaces.faces[5].second + ); + intersectedCount+= (bool)rel; + + if (intersectedCount > 0) return RayRelation::Intersect; + return RayRelation::None; +} \ No newline at end of file diff --git a/src/maths/rays.h b/src/maths/rays.h new file mode 100644 index 000000000..94293bb64 --- /dev/null +++ b/src/maths/rays.h @@ -0,0 +1,81 @@ +#ifndef MATHS_RAYS_H_ +#define MATHS_RAYS_H_ + +// #include "../typedefs.h" +#include "aabb.h" +#include "glm/glm.hpp" + +#include + +typedef glm::highp_dvec3 rayvec3; +typedef glm::highp_dvec2 rayvec2; + +enum class RayRelation{ + Embed=2, Intersect=1, Parallel=0, None=0 +}; +enum class AAFaceKind : unsigned char{ + Xperp=0, Yperp=1, Zperp=2 //perpendicular faces to corresponding axis +}; + +const unsigned char AABBFACES_COUNT = 6; + +class AABBFaces{ +public: + std::array, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point + + AABBFaces(){}; + AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox); + +}; + +template<> +struct std::hash{ + std::size_t operator()(const rayvec3& r) const noexcept{ + return std::hash{}(r.x) ^ (std::hash{}(r.y) << 1) ^ (std::hash{}(r.z) << 2); + } +}; + +class Rays{ +protected: + static const bool IS_RAYS_BOX_CACHE_ON = false; + static std::unordered_map raysBoxCache_; //[boxPos]: faces array + +public: + +template +static RayRelation rayIntersectAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner, + rayvec3& intersectPoint_ret + ); + +//optimized, not returns intersectPoint coordinates +template +static RayRelation isRayIntersectsAAFace( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& faceMin, + const rayvec2& faceOppositeCorner + ); + +static RayRelation rayIntersectAABB( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const rayvec3& boxPos, + const AABB& box, + rayvec3& pointIn_ret, + rayvec3& pointOut_ret, + glm::ivec3& normal_ret); + +static RayRelation rayIntersectAABBFaces( + const rayvec3& rayOrigin, + const rayvec3& rayDir, + const AABBFaces& boxFaces, + rayvec3& pointIn_ret, + rayvec3& pointOut_ret, + glm::ivec3& normal_ret); +}; + +#endif // SRC_VOXNATHS_H_ diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 7d46bc448..60172e6e1 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -10,6 +10,8 @@ #include "../graphics/Mesh.h" #include "../maths/voxmaths.h" +#include "../maths/aabb.h" +#include "../maths/rays.h" #include #include @@ -55,7 +57,7 @@ voxel* Chunks::get(int x, int y, int z){ if (z < 0) cz--; if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d) return nullptr; - shared_ptr chunk = chunks[(cy * d + cz) * w + cx]; + shared_ptr chunk = chunks[cz * w + cx]; // chunks is 2D-array if (chunk == nullptr) return nullptr; int lx = x - cx * CHUNK_W; @@ -175,6 +177,7 @@ void Chunks::set(int x, int y, int z, int id, uint8_t states){ chunk->setModified(true); } #include "../util/timeutil.h" +#include voxel* Chunks::rayCast(vec3 start, vec3 dir, float maxDist, @@ -212,33 +215,37 @@ voxel* Chunks::rayCast(vec3 start, float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; - int steppedIndex = -1; + int steppedIndex = -1; + + while (t <= maxDist){ + voxel* voxel = get(ix, iy, iz); + if (!voxel){ return nullptr; } - while (t <= maxDist){ - voxel* voxel = get(ix, iy, iz); - const Block* def = nullptr; - if (voxel == nullptr || (def = contentIds->getBlockDef(voxel->id))->selectable){ + const Block* def = contentIds->getBlockDef(voxel->id); + if (def->selectable){ timeutil::ScopeLogTimer lg((long long)def); end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; + iend.x = ix; + iend.y = iy; + iend.z = iz; - // TODO: replace this dumb solution with something better if (def && !def->rt.solid) { const int gridSize = BLOCK_AABB_GRID * 2; const AABB& box = def->rotatable ? def->rt.hitboxes[voxel->rotation()] : def->hitbox; - const int subs = gridSize; + /*const int subs = gridSize; iend = vec3(ix, iy, iz); - end -= iend; + end -= iend; // in-block coordinates int six = end.x * gridSize; int siy = end.y * gridSize; int siz = end.z * gridSize; float stxMax = (txDelta < infinity) ? txDelta * xdist : infinity; float styMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; float stzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; - for (int i = 0; i < subs*2; i++) { + for (int i = 0; i < subs*3; i++) { end.x = six / float(gridSize); end.y = siy / float(gridSize); end.z = siz / float(gridSize); @@ -271,7 +278,17 @@ voxel* Chunks::rayCast(vec3 start, steppedIndex = 2; } } + }*/ + rayvec3 in, out; + glm::ivec3 normal; + if ((bool)Rays::rayIntersectAABB(start, dir, iend, box, in, out, normal)){ + norm.x = norm.y = norm.z = 0.0f; + if (steppedIndex == 0) norm.x = -stepx; + if (steppedIndex == 1) norm.y = -stepy; + if (steppedIndex == 2) norm.z = -stepz; + return voxel; } + } else { iend.x = ix; iend.y = iy; From c5ab5996a38063c68424b0d42c43166467f14694 Mon Sep 17 00:00:00 2001 From: Ara Date: Sat, 9 Dec 2023 20:20:48 +0600 Subject: [PATCH 3/5] quickfix typo --- src/maths/rays.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/maths/rays.cpp b/src/maths/rays.cpp index 711c660fb..4a0a899f1 100644 --- a/src/maths/rays.cpp +++ b/src/maths/rays.cpp @@ -130,7 +130,7 @@ RayRelation Rays::rayIntersectAAFace( rayCoef*rayDir.y + rayOrigin.y, faceMin.z}; - if (rayDir.y > 0){ + if (rayDir.z > 0){ if (intersectPoint_ret.x >= faceMin.x //Face-hit check && intersectPoint_ret.x <= faceOppositeCorner[0] && intersectPoint_ret.y >= faceMin.y @@ -244,7 +244,7 @@ RayRelation Rays::isRayIntersectsAAFace( rayCoef*rayDir.y + rayOrigin.y * rayDir.z, faceMin.z * rayDir.z}; - if (rayDir.y > 0){ + if (rayDir.z > 0){ if (intersectPointMult.x >= faceMin.x * rayDir.z //Face-hit check && intersectPointMult.x <= faceOppositeCorner[0] * rayDir.z && intersectPointMult.y >= faceMin.y * rayDir.z From f5b5130e8b01c9e1232f9746b3f6cc28bc9ae8b5 Mon Sep 17 00:00:00 2001 From: Ara Date: Sat, 9 Dec 2023 22:36:36 +0600 Subject: [PATCH 4/5] small fixes --- src/frontend/gui/panels.h | 4 +- src/logic/PlayerController.cpp | 19 +++--- src/logic/PlayerController.h | 2 +- src/maths/rays.cpp | 107 +++++++++++++++------------------ src/maths/rays.h | 8 ++- src/util/timeutil.cpp | 2 +- src/voxels/Chunks.cpp | 73 ++++------------------ src/voxels/Chunks.h | 4 +- 8 files changed, 85 insertions(+), 134 deletions(-) diff --git a/src/frontend/gui/panels.h b/src/frontend/gui/panels.h index 1911abfc6..9480719fe 100644 --- a/src/frontend/gui/panels.h +++ b/src/frontend/gui/panels.h @@ -93,8 +93,8 @@ namespace gui { void back(); void clearHistory(); void reset(); -//comment or erase pragma if you hate notes.. -#pragma message("gui::PagesControl::current() returns Page by-value! (can initiate unexpected behaviour)") + +//FIXME "gui::PagesControl::current() returns Page by-value! (can initiate unexpected behaviour)") Page current(); }; } diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index acd72244d..f731f9e25 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -110,7 +110,7 @@ void CameraControl::update(PlayerInput& input, float delta) { vec3 PlayerController::selectedBlockPosition; vec3 PlayerController::selectedPointPosition; -vec3 PlayerController::selectedBlockNormal; +ivec3 PlayerController::selectedBlockNormal; int PlayerController::selectedBlockId = -1; int PlayerController::selectedBlockStates = 0; @@ -192,7 +192,8 @@ void PlayerController::updateInteraction(){ Lighting* lighting = level->lighting; Camera* camera = player->camera; vec3 end; - vec3 norm; + ivec3 iend; + ivec3 norm; bool xkey = Events::pressed(keycode::X); bool lclick = Events::jactive(BIND_PLAYER_ATTACK) || @@ -203,7 +204,7 @@ void PlayerController::updateInteraction(){ if (xkey) { maxDistance *= 20.0f; } - vec3 iend; + voxel* vox = chunks->rayCast(camera->position, camera->front, maxDistance, @@ -215,9 +216,9 @@ void PlayerController::updateInteraction(){ selectedBlockPosition = iend; selectedPointPosition = end; selectedBlockNormal = norm; - int x = (int)iend.x; - int y = (int)iend.y; - int z = (int)iend.z; + int x = iend.x; + int y = iend.y; + int z = iend.z; uint8_t states = 0; Block* def = contentIds->getBlockDef(player->choosenBlock); @@ -250,9 +251,9 @@ void PlayerController::updateInteraction(){ } if (rclick){ if (block->model != BlockModel::xsprite){ - x = (int)(iend.x)+(int)(norm.x); - y = (int)(iend.y)+(int)(norm.y); - z = (int)(iend.z)+(int)(norm.z); + x = (iend.x)+(norm.x); + y = (iend.y)+(norm.y); + z = (iend.z)+(norm.z); } vox = chunks->get(x, y, z); if (vox && (block = contentIds->getBlockDef(vox->id))->replaceable) { diff --git a/src/logic/PlayerController.h b/src/logic/PlayerController.h index a2f7ccf95..158b0b87e 100644 --- a/src/logic/PlayerController.h +++ b/src/logic/PlayerController.h @@ -37,7 +37,7 @@ class PlayerController { void updateInteraction(); public: static glm::vec3 selectedBlockPosition; - static glm::vec3 selectedBlockNormal; + static glm::ivec3 selectedBlockNormal; static glm::vec3 selectedPointPosition; static int selectedBlockId; static int selectedBlockStates; diff --git a/src/maths/rays.cpp b/src/maths/rays.cpp index 4a0a899f1..868c479fc 100644 --- a/src/maths/rays.cpp +++ b/src/maths/rays.cpp @@ -4,22 +4,18 @@ #include "glm/glm.hpp" -constexpr std::array AABBFACES_KINDS_ORDER = { - AAFaceKind::Xperp, AAFaceKind::Xperp, - AAFaceKind::Yperp, AAFaceKind::Yperp, - AAFaceKind::Zperp, AAFaceKind::Zperp}; std::unordered_map Rays::raysBoxCache_ = {}; const rayvec3 X_AXIS = rayvec3(1,0,0), Y_AXIS = rayvec3(0,1,0), Z_AXIS = rayvec3(0,0,1); -//make edges from AABB +//make faces from AABB AABBFaces::AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox){ - rayvec3 pbMin = parentBox.min(), + rayvec3 pbMin = parentBox.min(), // every face is min-point and opposite corner point pbMax = parentBox.max(), pbRealPos = parentBoxPos + pbMin; rayvec2 yzMax = rayvec2(parentBoxPos.y + pbMax.y, parentBoxPos.z + pbMax.z ), xzMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.z + pbMax.z ), xyMax = rayvec2(parentBoxPos.x + pbMax.x, parentBoxPos.y + pbMax.y ); - faces[0] = {pbRealPos, yzMax}; + faces[0] = {pbRealPos, yzMax}; //in order of AABBFaces::KINDS_ORDER! faces[1] = {parentBoxPos + rayvec3(pbMax.x, pbMin.y, pbMin.z), yzMax}; @@ -41,9 +37,6 @@ RayRelation Rays::rayIntersectAAFace( rayvec3& intersectPoint_ret ){ if (fabs(glm::dot(rayDir, X_AXIS)) < 1.0E-8){ //precision - if (rayOrigin.x == faceMin.x) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } return RayRelation::Parallel; } @@ -80,9 +73,6 @@ RayRelation Rays::rayIntersectAAFace( rayvec3& intersectPoint_ret ){ if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision - if (rayOrigin.y == faceMin.y) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } return RayRelation::Parallel; } @@ -119,9 +109,6 @@ RayRelation Rays::rayIntersectAAFace( rayvec3& intersectPoint_ret ){ if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision - if (rayOrigin.z == faceMin.z) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } return RayRelation::Parallel; } @@ -154,12 +141,10 @@ RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayOrigin, const rayvec3& rayDir, const rayvec3& faceMin, - const rayvec2& faceOppositeCorner + const rayvec2& faceOppositeCorner, + glm::ivec3& normal_ret ){ if (fabs(glm::dot(rayDir, X_AXIS)) < 1.0E-8){ //precision of "parallelity" - if (rayOrigin.x == faceMin.x) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } return RayRelation::Parallel; } @@ -192,12 +177,10 @@ RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayOrigin, const rayvec3& rayDir, const rayvec3& faceMin, - const rayvec2& faceOppositeCorner + const rayvec2& faceOppositeCorner, + glm::ivec3& normal_ret ){ - if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision - if (rayOrigin.y == faceMin.y) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } + if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision of "parallelity" return RayRelation::Parallel; } @@ -230,12 +213,10 @@ RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayOrigin, const rayvec3& rayDir, const rayvec3& faceMin, - const rayvec2& faceOppositeCorner + const rayvec2& faceOppositeCorner, + glm::ivec3& normal_ret ){ - if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision - if (rayOrigin.z == faceMin.z) { - return RayRelation::Embed; // there can be check of hit, but not necessarily - } + if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision of "parallelity" return RayRelation::Parallel; } @@ -295,39 +276,51 @@ RayRelation Rays::rayIntersectAABBFaces( const AABBFaces& boxFaces, rayvec3& pointIn_ret, rayvec3& pointOut_ret, - glm::ivec3& normal_ret){//TODO: refs update + glm::ivec3& normal_ret){//TODO: points returning RayRelation rel; - unsigned char intersectedCount = 0; - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[0].first, boxFaces.faces[0].second - ); - intersectedCount+= (bool)rel; - - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[1].first, boxFaces.faces[1].second - ); - intersectedCount+= (bool)rel; + unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT! + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[0].first, boxFaces.faces[0].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[2].first, boxFaces.faces[2].second - ); - intersectedCount+= (bool)rel; + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[1].first, boxFaces.faces[1].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[3].first, boxFaces.faces[3].second - ); - intersectedCount+= (bool)rel; + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[2].first, boxFaces.faces[2].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[4].first, boxFaces.faces[4].second - ); - intersectedCount+= (bool)rel; + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[3].first, boxFaces.faces[3].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } - rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[5].first, boxFaces.faces[5].second - ); - intersectedCount+= (bool)rel; + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[4].first, boxFaces.faces[4].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } + rel = isRayIntersectsAAFace( + rayOrigin, rayDir, boxFaces.faces[5].first, boxFaces.faces[5].second, normal_ret + ); + if (rel > RayRelation::None){ + ++intersectedCount; + } + if (intersectedCount > 0) return RayRelation::Intersect; return RayRelation::None; } \ No newline at end of file diff --git a/src/maths/rays.h b/src/maths/rays.h index 94293bb64..1b04b2573 100644 --- a/src/maths/rays.h +++ b/src/maths/rays.h @@ -23,6 +23,11 @@ class AABBFaces{ public: std::array, AABBFACES_COUNT> faces; // every face is min-point and opposite corner point + static constexpr std::array KINDS_ORDER = { + AAFaceKind::Xperp, AAFaceKind::Xperp, + AAFaceKind::Yperp, AAFaceKind::Yperp, + AAFaceKind::Zperp, AAFaceKind::Zperp}; + AABBFaces(){}; AABBFaces(const rayvec3& parentBoxPos, const AABB& parentBox); @@ -57,7 +62,8 @@ static RayRelation isRayIntersectsAAFace( const rayvec3& rayOrigin, const rayvec3& rayDir, const rayvec3& faceMin, - const rayvec2& faceOppositeCorner + const rayvec2& faceOppositeCorner, + glm::ivec3& normal_ret ); static RayRelation rayIntersectAABB( diff --git a/src/util/timeutil.cpp b/src/util/timeutil.cpp index 04be381f5..e299bec11 100644 --- a/src/util/timeutil.cpp +++ b/src/util/timeutil.cpp @@ -16,7 +16,7 @@ int64_t timeutil::Timer::stop() { timeutil::ScopeLogTimer::ScopeLogTimer(long long id) : scopeid_(id) {} timeutil::ScopeLogTimer::~ScopeLogTimer() { - std::cout << "Scope "<< scopeid_ <<" finished in "<< ScopeLogTimer::stop() << " micros."< using glm::vec3; +using glm::ivec3; using std::shared_ptr; Chunks::Chunks(int w, int d, @@ -177,13 +178,12 @@ void Chunks::set(int x, int y, int z, int id, uint8_t states){ chunk->setModified(true); } #include "../util/timeutil.h" -#include voxel* Chunks::rayCast(vec3 start, vec3 dir, float maxDist, vec3& end, - vec3& norm, - vec3& iend) { + ivec3& norm, + ivec3& iend) { float px = start.x; float py = start.y; float pz = start.z; @@ -197,9 +197,9 @@ voxel* Chunks::rayCast(vec3 start, int iy = floor(py); int iz = floor(pz); - float stepx = (dx > 0.0f) ? 1.0f : -1.0f; - float stepy = (dy > 0.0f) ? 1.0f : -1.0f; - float stepz = (dz > 0.0f) ? 1.0f : -1.0f; + int stepx = (dx > 0.0f) ? 1 : -1; + int stepy = (dy > 0.0f) ? 1 : -1; + int stepz = (dz > 0.0f) ? 1 : -1; constexpr float infinity = std::numeric_limits::infinity(); @@ -223,7 +223,7 @@ voxel* Chunks::rayCast(vec3 start, const Block* def = contentIds->getBlockDef(voxel->id); if (def->selectable){ - timeutil::ScopeLogTimer lg((long long)def); + //timeutil::ScopeLogTimer lg((long long)def); end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; @@ -231,61 +231,12 @@ voxel* Chunks::rayCast(vec3 start, iend.y = iy; iend.z = iz; - if (def && !def->rt.solid) { - const int gridSize = BLOCK_AABB_GRID * 2; + if (!def->rt.solid) { const AABB& box = def->rotatable ? def->rt.hitboxes[voxel->rotation()] : def->hitbox; - /*const int subs = gridSize; - iend = vec3(ix, iy, iz); - end -= iend; // in-block coordinates - int six = end.x * gridSize; - int siy = end.y * gridSize; - int siz = end.z * gridSize; - float stxMax = (txDelta < infinity) ? txDelta * xdist : infinity; - float styMax = (tyDelta < infinity) ? tyDelta * ydist : infinity; - float stzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity; - for (int i = 0; i < subs*3; i++) { - end.x = six / float(gridSize); - end.y = siy / float(gridSize); - end.z = siz / float(gridSize); - if (box.inside(end)) { - end += iend; - norm.x = norm.y = norm.z = 0.0f; - if (steppedIndex == 0) norm.x = -stepx; - if (steppedIndex == 1) norm.y = -stepy; - if (steppedIndex == 2) norm.z = -stepz; - return voxel; - } - if (stxMax < styMax) { - if (stxMax < stzMax) { - six += stepx; - stxMax += txDelta; - steppedIndex = 0; - } else { - siz += stepz; - stzMax += tzDelta; - steppedIndex = 2; - } - } else { - if (styMax < stzMax) { - siy += stepy; - styMax += tyDelta; - steppedIndex = 1; - } else { - siz += stepz; - stzMax += tzDelta; - steppedIndex = 2; - } - } - }*/ - rayvec3 in, out; - glm::ivec3 normal; - if ((bool)Rays::rayIntersectAABB(start, dir, iend, box, in, out, normal)){ - norm.x = norm.y = norm.z = 0.0f; - if (steppedIndex == 0) norm.x = -stepx; - if (steppedIndex == 1) norm.y = -stepy; - if (steppedIndex == 2) norm.z = -stepz; + rayvec3 in, out; // <- now not used, but for future... + if (Rays::rayIntersectAABB(start, dir, iend, box, in, out, norm) > RayRelation::None){ return voxel; } @@ -294,7 +245,7 @@ voxel* Chunks::rayCast(vec3 start, iend.y = iy; iend.z = iz; - norm.x = norm.y = norm.z = 0.0f; + norm.x = norm.y = norm.z = 0; if (steppedIndex == 0) norm.x = -stepx; if (steppedIndex == 1) norm.y = -stepy; if (steppedIndex == 2) norm.z = -stepz; @@ -334,7 +285,7 @@ voxel* Chunks::rayCast(vec3 start, end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; - norm.x = norm.y = norm.z = 0.0f; + norm.x = norm.y = norm.z = 0; return nullptr; } diff --git a/src/voxels/Chunks.h b/src/voxels/Chunks.h index 687499f22..78ed84bb4 100644 --- a/src/voxels/Chunks.h +++ b/src/voxels/Chunks.h @@ -48,8 +48,8 @@ class Chunks { glm::vec3 dir, float maxLength, glm::vec3& end, - glm::vec3& norm, - glm::vec3& iend); + glm::ivec3& norm, + glm::ivec3& iend); const AABB* isObstacle(float x, float y, float z); From 616057b2b93f8d0e054974030f21994f79bfc8f6 Mon Sep 17 00:00:00 2001 From: Ara Date: Sun, 10 Dec 2023 00:38:32 +0600 Subject: [PATCH 5/5] normals finished --- src/maths/rays.cpp | 49 ++++++++++++++++++++++++++++++++----------- src/maths/rays.h | 12 ++++++++++- src/voxels/Chunks.cpp | 4 ++-- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/maths/rays.cpp b/src/maths/rays.cpp index 868c479fc..450fdf753 100644 --- a/src/maths/rays.cpp +++ b/src/maths/rays.cpp @@ -136,13 +136,27 @@ RayRelation Rays::rayIntersectAAFace( return RayRelation::None; } +double Rays::updateNormal( + double newDistApprox, + const glm::ivec3& newNormal, + double currentDistApprox, + glm::ivec3& normal_ret + ){ + if (newDistApprox < currentDistApprox){ + currentDistApprox = newDistApprox; + normal_ret = newNormal; + } + return currentDistApprox; + } + template <> RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayOrigin, const rayvec3& rayDir, const rayvec3& faceMin, const rayvec2& faceOppositeCorner, - glm::ivec3& normal_ret + glm::ivec3& normal_ret, + double& currentDistApprox ){ if (fabs(glm::dot(rayDir, X_AXIS)) < 1.0E-8){ //precision of "parallelity" return RayRelation::Parallel; @@ -158,6 +172,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.y <= faceOppositeCorner[0] * rayDir.x && intersectPointMult.z >= faceMin.z * rayDir.x && intersectPointMult.z <= faceOppositeCorner[1] * rayDir.x){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.y * rayDir.z), -X_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -166,6 +181,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.y >= faceOppositeCorner[0] * rayDir.x && intersectPointMult.z <= faceMin.z * rayDir.x && intersectPointMult.z >= faceOppositeCorner[1] * rayDir.x){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.y * rayDir.z), X_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -178,7 +194,8 @@ RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayDir, const rayvec3& faceMin, const rayvec2& faceOppositeCorner, - glm::ivec3& normal_ret + glm::ivec3& normal_ret, + double& currentDistApprox ){ if (fabs(glm::dot(rayDir, Y_AXIS)) < 1.0E-8){ //precision of "parallelity" return RayRelation::Parallel; @@ -194,6 +211,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.x <= faceOppositeCorner[0] * rayDir.y && intersectPointMult.z >= faceMin.z * rayDir.y && intersectPointMult.z <= faceOppositeCorner[1] * rayDir.y){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.x * rayDir.z), -Y_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -202,6 +220,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.x >= faceOppositeCorner[0] * rayDir.y && intersectPointMult.z <= faceMin.z * rayDir.y && intersectPointMult.z >= faceOppositeCorner[1] * rayDir.y){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.x * rayDir.z), Y_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -214,7 +233,8 @@ RayRelation Rays::isRayIntersectsAAFace( const rayvec3& rayDir, const rayvec3& faceMin, const rayvec2& faceOppositeCorner, - glm::ivec3& normal_ret + glm::ivec3& normal_ret, + double& currentDistApprox ){ if (fabs(glm::dot(rayDir, Z_AXIS)) < 1.0E-8){ //precision of "parallelity" return RayRelation::Parallel; @@ -230,6 +250,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.x <= faceOppositeCorner[0] * rayDir.z && intersectPointMult.y >= faceMin.y * rayDir.z && intersectPointMult.y <= faceOppositeCorner[1] * rayDir.z){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.x * rayDir.y), -Z_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -238,6 +259,7 @@ RayRelation Rays::isRayIntersectsAAFace( && intersectPointMult.x >= faceOppositeCorner[0] * rayDir.z && intersectPointMult.y <= faceMin.y * rayDir.z && intersectPointMult.y >= faceOppositeCorner[1] * rayDir.z){ + currentDistApprox = updateNormal(fabs(rayCoef * rayDir.x * rayDir.y), Z_AXIS, currentDistApprox, normal_ret); return RayRelation::Intersect; } } @@ -249,6 +271,7 @@ RayRelation Rays::rayIntersectAABB( const rayvec3& rayDir, const rayvec3& boxPos, const AABB& box, + float maxDist, rayvec3& pointIn_ret, rayvec3& pointOut_ret, glm::ivec3& normal_ret){ @@ -256,16 +279,16 @@ RayRelation Rays::rayIntersectAABB( if (raysBoxCache_.find(boxPos) != raysBoxCache_.end()){ const AABBFaces& boxFaces = raysBoxCache_[boxPos]; - return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, maxDist, pointIn_ret, pointOut_ret, normal_ret); } else { const AABBFaces& boxFaces = AABBFaces(boxPos, box); raysBoxCache_[boxPos] = boxFaces; - return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, maxDist, pointIn_ret, pointOut_ret, normal_ret); } } else { const AABBFaces& boxFaces = AABBFaces(boxPos, box); - return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, pointIn_ret, pointOut_ret, normal_ret); + return rayIntersectAABBFaces(rayOrigin, rayDir, boxFaces, maxDist, pointIn_ret, pointOut_ret, normal_ret); } } @@ -274,48 +297,50 @@ RayRelation Rays::rayIntersectAABBFaces( const rayvec3& rayOrigin, const rayvec3& rayDir, const AABBFaces& boxFaces, + float maxDist, rayvec3& pointIn_ret, rayvec3& pointOut_ret, glm::ivec3& normal_ret){//TODO: points returning RayRelation rel; + double faceDistApprox = maxDist; unsigned char intersectedCount = 0; //this code is very uncomfortable, DONT LEARN IT! rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[0].first, boxFaces.faces[0].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[0].first, boxFaces.faces[0].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; } rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[1].first, boxFaces.faces[1].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[1].first, boxFaces.faces[1].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; } rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[2].first, boxFaces.faces[2].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[2].first, boxFaces.faces[2].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; } rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[3].first, boxFaces.faces[3].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[3].first, boxFaces.faces[3].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; } rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[4].first, boxFaces.faces[4].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[4].first, boxFaces.faces[4].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; } rel = isRayIntersectsAAFace( - rayOrigin, rayDir, boxFaces.faces[5].first, boxFaces.faces[5].second, normal_ret + rayOrigin, rayDir, boxFaces.faces[5].first, boxFaces.faces[5].second, normal_ret, faceDistApprox ); if (rel > RayRelation::None){ ++intersectedCount; diff --git a/src/maths/rays.h b/src/maths/rays.h index 1b04b2573..bf6c7e766 100644 --- a/src/maths/rays.h +++ b/src/maths/rays.h @@ -56,6 +56,13 @@ static RayRelation rayIntersectAAFace( rayvec3& intersectPoint_ret ); +static double updateNormal( + double newDistApprox, + const glm::ivec3& newNormal, + double currentDistApprox, + glm::ivec3& normal_ret + ); + //optimized, not returns intersectPoint coordinates template static RayRelation isRayIntersectsAAFace( @@ -63,7 +70,8 @@ static RayRelation isRayIntersectsAAFace( const rayvec3& rayDir, const rayvec3& faceMin, const rayvec2& faceOppositeCorner, - glm::ivec3& normal_ret + glm::ivec3& normal_ret, + double& currentDistApprox ); static RayRelation rayIntersectAABB( @@ -71,6 +79,7 @@ static RayRelation rayIntersectAABB( const rayvec3& rayDir, const rayvec3& boxPos, const AABB& box, + float maxDist, rayvec3& pointIn_ret, rayvec3& pointOut_ret, glm::ivec3& normal_ret); @@ -79,6 +88,7 @@ static RayRelation rayIntersectAABBFaces( const rayvec3& rayOrigin, const rayvec3& rayDir, const AABBFaces& boxFaces, + float maxDist, rayvec3& pointIn_ret, rayvec3& pointOut_ret, glm::ivec3& normal_ret); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 8899d617a..497bb0826 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -223,7 +223,7 @@ voxel* Chunks::rayCast(vec3 start, const Block* def = contentIds->getBlockDef(voxel->id); if (def->selectable){ - //timeutil::ScopeLogTimer lg((long long)def); + timeutil::ScopeLogTimer lg((long long)def); end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; @@ -236,7 +236,7 @@ voxel* Chunks::rayCast(vec3 start, ? def->rt.hitboxes[voxel->rotation()] : def->hitbox; rayvec3 in, out; // <- now not used, but for future... - if (Rays::rayIntersectAABB(start, dir, iend, box, in, out, norm) > RayRelation::None){ + if (Rays::rayIntersectAABB(start, dir, iend, box, maxDist, in, out, norm) > RayRelation::None){ return voxel; }