diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-07-14 18:55:25 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-09-29 22:33:13 +0200 |
commit | 2624ccd8ba673ba79a99d24357458d763ac1e4c3 (patch) | |
tree | 828faffcf7e50de282a2424e58fa4afb48ea6e91 | |
parent | Box size changes (diff) | |
download | cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar.gz cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar.bz2 cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar.lz cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar.xz cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.tar.zst cuberite-2624ccd8ba673ba79a99d24357458d763ac1e4c3.zip |
-rw-r--r-- | src/BoundingBox.cpp | 16 | ||||
-rw-r--r-- | src/Entities/Entity.cpp | 25 |
2 files changed, 27 insertions, 14 deletions
diff --git a/src/BoundingBox.cpp b/src/BoundingBox.cpp index 1356e165c..e60be3476 100644 --- a/src/BoundingBox.cpp +++ b/src/BoundingBox.cpp @@ -213,41 +213,45 @@ bool cBoundingBox::CalcLineIntersection(Vector3d a_Min, Vector3d a_Max, Vector3d return true; } + // Correction for floating point imprecision when calculating + // the coefficient to intersect a plane by slightly increasing it + static const auto Correction = 1.000001; + eBlockFace Face = BLOCK_FACE_NONE; double Coeff = Vector3d::NO_INTERSECTION; // Check each individual bbox face for intersection with the line, remember the one with the lowest coeff - double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z); + double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } - c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z); + c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } - c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y); + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } - c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y); + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } - c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x); + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; Coeff = c; } - c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x); + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x) * Correction; if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 37ef925cf..1f270cff0 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1067,9 +1067,15 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) // TODO: checks too much, very inefficient for (int i = bstart.x; i <= bend.x; i++) - for (int j = bstart.y; j <= bend.y; j++) - for (int k = bstart.z; k <= bend.z; k++) - Checks.emplace(Vector3i(i, j, k)); + { + for (int j = bstart.y; j <= bend.y; j++) + { + for (int k = bstart.z; k <= bend.z; k++) + { + Checks.emplace(Vector3i(i, j, k)); + } + } + } return Checks; } @@ -1146,15 +1152,18 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) eBlockFace Face; // Face hit cBoundingBox bb(a_BlockPos, a_BlockPos + Vector3i(1, 1, 1)); // Bounding box of the block hit + // First calculate line intersection if (!bb.CalcLineIntersection(m_Start, m_End, LineCoeff, Face)) { - // Math rounding errors have caused the calculation to miss the block completely, assume immediate hit - LineCoeff = 0; + // Maths rounding errors have caused the calculation to miss the block completely + m_HitCoords = m_End; + m_HitBlockFace = BLOCK_FACE_NONE; + return true; } - m_HitCoords = m_Start + (m_End - m_Start) * LineCoeff; // Point where projectile goes into the hit block - - TestBoundingBoxCollisionWithEnvironment(m_HitCoords); + // Check bbox collision, setting final values + // Line tracer hit position is used as a starting point: + TestBoundingBoxCollisionWithEnvironment(m_Start + (m_End - m_Start) * LineCoeff); return m_HitBlockFace != BLOCK_FACE_NONE; } |