react-native-cesium 1.2.10 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cpp/engine/CesiumEngine.cpp +97 -18
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#endif
|
|
5
5
|
|
|
6
6
|
#include "CesiumEngine.hpp"
|
|
7
|
+
#include "GeoidConverter.hpp"
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
#include <Cesium3DTilesContent/registerAllTileContentTypes.h>
|
|
@@ -608,10 +609,26 @@ void CesiumEngine::updateFrame(double w, double h, FrameResult& result) {
|
|
|
608
609
|
const CameraParams camParams = trackTerrainFloor ? camera_.getParams() : CameraParams{};
|
|
609
610
|
const double camLatRad = glm::radians(camParams.latitude);
|
|
610
611
|
const double camLonRad = glm::radians(camParams.longitude);
|
|
612
|
+
|
|
613
|
+
// Expected ground ellipsoid height at camera location (from geoid).
|
|
614
|
+
// Used to filter out elevated structures (buildings) during floor sampling.
|
|
615
|
+
const double expectedGroundEllipsoid = trackTerrainFloor
|
|
616
|
+
? mslToEllipsoidMeters(camParams.latitude, camParams.longitude, 0.0)
|
|
617
|
+
: 0.0;
|
|
618
|
+
|
|
611
619
|
float bestTerrainFloor = terrainFloorEllipsoidM_; // carry previous value if no tile matches
|
|
612
620
|
double bestHorizDistSq = std::numeric_limits<double>::max();
|
|
613
621
|
bool floorScanFound = false;
|
|
614
622
|
|
|
623
|
+
// Horizontal search radius for floor sampling.
|
|
624
|
+
constexpr double kFloorSearchRadiusM = 50.0;
|
|
625
|
+
constexpr double kFloorSearchRadiusSq = kFloorSearchRadiusM * kFloorSearchRadiusM;
|
|
626
|
+
// Only accept vertices within this tolerance of expected ground (filters out buildings).
|
|
627
|
+
constexpr double kGroundToleranceM = 10.0;
|
|
628
|
+
// 3D fallback: if no ground-level vertices found, use closest 3D vertex.
|
|
629
|
+
double bestDist3D = std::numeric_limits<double>::max();
|
|
630
|
+
float bestDist3DFloor = 0.0f;
|
|
631
|
+
|
|
615
632
|
// ── floor-scan cache lookup ─────────────────────────────────────────
|
|
616
633
|
// Skip the per-vertex scan when the camera has moved less than ~10 cm in
|
|
617
634
|
// both lat and lon AND the visible primitive set is unchanged (same
|
|
@@ -675,22 +692,53 @@ void CesiumEngine::updateFrame(double w, double h, FrameResult& result) {
|
|
|
675
692
|
for (size_t vi = 0; vi < vc; ++vi) {
|
|
676
693
|
const glm::dvec3 vECEF =
|
|
677
694
|
glm::dvec3(prim.localPositions[vi]) + prim.rtcCenter;
|
|
678
|
-
const glm::dvec3 delta
|
|
679
|
-
const double de
|
|
680
|
-
const double dn
|
|
695
|
+
const glm::dvec3 delta = vECEF - cameraPos;
|
|
696
|
+
const double de = glm::dot(delta, floorEast);
|
|
697
|
+
const double dn = glm::dot(delta, floorNorth);
|
|
681
698
|
const double horizSq = de * de + dn * dn;
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
699
|
+
const float vAlt = prim.altitudes[vi];
|
|
700
|
+
|
|
701
|
+
// Primary: horizontal search within radius, only accept vertices near ground level.
|
|
702
|
+
// This filters out elevated structures (buildings) in urban areas.
|
|
703
|
+
if (horizSq <= kFloorSearchRadiusSq) {
|
|
704
|
+
const double heightAboveGround = static_cast<double>(vAlt) - expectedGroundEllipsoid;
|
|
705
|
+
if (heightAboveGround >= -kGroundToleranceM &&
|
|
706
|
+
heightAboveGround <= kGroundToleranceM) {
|
|
707
|
+
if (!floorScanFound || vAlt < bestTerrainFloor) {
|
|
708
|
+
bestTerrainFloor = vAlt;
|
|
709
|
+
bestHorizDistSq = horizSq;
|
|
710
|
+
floorScanFound = true;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// Fallback: track closest 3D vertex for sparse/ocean scenarios.
|
|
716
|
+
const double dist3D = glm::length(delta);
|
|
717
|
+
if (dist3D < bestDist3D) {
|
|
718
|
+
bestDist3D = dist3D;
|
|
719
|
+
bestDist3DFloor = vAlt;
|
|
690
720
|
}
|
|
691
721
|
}
|
|
692
722
|
}
|
|
693
723
|
}
|
|
724
|
+
// Fallback: if no ground-level vertices found, use expected ground from geoid.
|
|
725
|
+
// This handles urban areas where terrain tiles only contain building structures.
|
|
726
|
+
if (!floorScanFound) {
|
|
727
|
+
if (bestDist3D < std::numeric_limits<double>::max()) {
|
|
728
|
+
// Use closest 3D vertex only if it's near ground level
|
|
729
|
+
const double heightAboveGround = static_cast<double>(bestDist3DFloor) - expectedGroundEllipsoid;
|
|
730
|
+
if (heightAboveGround >= -kGroundToleranceM &&
|
|
731
|
+
heightAboveGround <= kGroundToleranceM) {
|
|
732
|
+
bestTerrainFloor = bestDist3DFloor;
|
|
733
|
+
floorScanFound = true;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
// Ultimate fallback: use geoid-based ground estimate
|
|
737
|
+
if (!floorScanFound) {
|
|
738
|
+
bestTerrainFloor = static_cast<float>(expectedGroundEllipsoid);
|
|
739
|
+
floorScanFound = true;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
694
742
|
}
|
|
695
743
|
|
|
696
744
|
const glm::dvec3 rtcCamRel = c.rtcCenter - glm::dvec3(cameraPos);
|
|
@@ -791,16 +839,47 @@ void CesiumEngine::updateFrame(double w, double h, FrameResult& result) {
|
|
|
791
839
|
const double de = glm::dot(delta, floorEast);
|
|
792
840
|
const double dn = glm::dot(delta, floorNorth);
|
|
793
841
|
const double horizSq = de * de + dn * dn;
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
842
|
+
const float vAlt = prim.altitudes[vi];
|
|
843
|
+
|
|
844
|
+
// Primary: horizontal search within radius, only accept vertices near ground level.
|
|
845
|
+
// This filters out elevated structures (buildings) in urban areas.
|
|
846
|
+
if (horizSq <= kFloorSearchRadiusSq) {
|
|
847
|
+
const double heightAboveGround = static_cast<double>(vAlt) - expectedGroundEllipsoid;
|
|
848
|
+
if (heightAboveGround >= -kGroundToleranceM &&
|
|
849
|
+
heightAboveGround <= kGroundToleranceM) {
|
|
850
|
+
if (!floorScanFound || vAlt < bestTerrainFloor) {
|
|
851
|
+
bestTerrainFloor = vAlt;
|
|
852
|
+
bestHorizDistSq = horizSq;
|
|
853
|
+
floorScanFound = true;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// Fallback: track closest 3D vertex for sparse/ocean scenarios.
|
|
859
|
+
const double dist3D = glm::length(delta);
|
|
860
|
+
if (dist3D < bestDist3D) {
|
|
861
|
+
bestDist3D = dist3D;
|
|
862
|
+
bestDist3DFloor = vAlt;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
// Fallback: if no ground-level vertices found, use expected ground from geoid.
|
|
867
|
+
// This handles urban areas where terrain tiles only contain building structures.
|
|
868
|
+
if (!floorScanFound) {
|
|
869
|
+
if (bestDist3D < std::numeric_limits<double>::max()) {
|
|
870
|
+
// Use closest 3D vertex only if it's near ground level
|
|
871
|
+
const double heightAboveGround = static_cast<double>(bestDist3DFloor) - expectedGroundEllipsoid;
|
|
872
|
+
if (heightAboveGround >= -kGroundToleranceM &&
|
|
873
|
+
heightAboveGround <= kGroundToleranceM) {
|
|
874
|
+
bestTerrainFloor = bestDist3DFloor;
|
|
797
875
|
floorScanFound = true;
|
|
798
|
-
} else if (horizSq <= bestHorizDistSq * (1.0 + 1e-9) + 1e-4) {
|
|
799
|
-
bestTerrainFloor =
|
|
800
|
-
std::min(bestTerrainFloor, prim.altitudes[vi]);
|
|
801
|
-
floorScanFound = true;
|
|
802
876
|
}
|
|
803
877
|
}
|
|
878
|
+
// Ultimate fallback: use geoid-based ground estimate
|
|
879
|
+
if (!floorScanFound) {
|
|
880
|
+
bestTerrainFloor = static_cast<float>(expectedGroundEllipsoid);
|
|
881
|
+
floorScanFound = true;
|
|
882
|
+
}
|
|
804
883
|
}
|
|
805
884
|
}
|
|
806
885
|
}
|