From 8e66b81d9814075eb64b60a93843ad90413d8f01 Mon Sep 17 00:00:00 2001 From: "hei_ke@sina.com" Date: Wed, 3 Jun 2026 14:33:33 +0800 Subject: [PATCH] fix: preserve MXCSR around earcut triangulation to support UE5 builds UE5 enables SSE DAZ (Denormals Are Zero) and FTZ (Flush To Zero) MXCSR flags on worker threads in packaged Development/Shipping builds. These flags cause mapbox::earcut's floating-point geometry predicates (signed area, point-in-triangle, etc.) to flush denormal intermediate values to zero, producing incorrect triangulation results for polygons with near-collinear vertices. --- CesiumGeospatial/src/CartographicPolygon.cpp | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CesiumGeospatial/src/CartographicPolygon.cpp b/CesiumGeospatial/src/CartographicPolygon.cpp index 0e963d0b12..55785499dc 100644 --- a/CesiumGeospatial/src/CartographicPolygon.cpp +++ b/CesiumGeospatial/src/CartographicPolygon.cpp @@ -16,6 +16,13 @@ #include #include + +#if defined(_MSC_VER) +#include +#elif defined(__x86_64__) || defined(__i386__) +#include +#endif + using namespace CesiumGeometry; namespace CesiumGeospatial { @@ -57,7 +64,21 @@ triangulatePolygon(const std::vector& polygon) { localPolygons.emplace_back(std::move(localPolygon)); + // Save the current MXCSR state and disable DAZ (bit 6) and FTZ (bit 15) + // before calling mapbox::earcut. These flags, enabled by UE5 in packaged + // builds, cause earcut's floating-point predicates to produce incorrect + // triangulation results by flushing denormal values to zero. +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) + unsigned int _oldMxcsr = _mm_getcsr(); + _mm_setcsr(_oldMxcsr & ~((1u << 6) | (1u << 15))); +#endif + indices = mapbox::earcut(localPolygons); + +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) + _mm_setcsr(_oldMxcsr); +#endif + return indices; } @@ -296,4 +317,4 @@ CartographicPolygon::CartographicPolygon(const std::vector& polygon) return true; } -} // namespace CesiumGeospatial +} // namespace CesiumGeospatial \ No newline at end of file