From baa0e0c35cdbf98d36c71e8ee0cecedc2533b1e8 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 6 Jun 2024 17:11:47 -0400 Subject: [PATCH 01/14] Support custom ellipsoid in Unity --- Editor/CesiumGeoreferenceEditor.cs | 14 ++++ Runtime/CesiumEllipsoid.cs | 48 +++++++++++++ Runtime/CesiumEllipsoid.cs.meta | 11 +++ Runtime/CesiumFlyToController.cs | 5 +- Runtime/CesiumGeoreference.cs | 22 ++++++ Runtime/CesiumSimplePlanarEllipsoidCurve.cs | 12 ++-- Runtime/ConfigureReinterop.cs | 10 ++- Tests/TestCesiumSimplePlanarEllipsoidCurve.cs | 4 +- native~/Runtime/src/CameraManager.cpp | 18 ++++- native~/Runtime/src/Cesium3DTilesetImpl.cpp | 21 ++++-- .../src/CesiumBingMapsRasterOverlayImpl.cpp | 2 +- .../Runtime/src/CesiumEllipsoidFunctions.cpp | 70 +++++++++++++++++++ .../Runtime/src/CesiumEllipsoidFunctions.h | 26 +++++++ native~/Runtime/src/CesiumEllipsoidImpl.cpp | 69 ++++++++++++++++++ native~/Runtime/src/CesiumEllipsoidImpl.h | 53 ++++++++++++++ .../src/CesiumFeaturesMetadataUtility.cpp | 2 +- .../Runtime/src/CesiumGeoreferenceImpl.cpp | 7 +- native~/Runtime/src/CesiumGlobeAnchorImpl.cpp | 33 +++++++-- native~/Runtime/src/CesiumMetadataImpl.cpp | 4 +- .../src/CesiumPolygonRasterOverlayImpl.cpp | 6 +- .../CesiumSimplePlanarEllipsoidCurveImpl.cpp | 6 +- .../CesiumSimplePlanarEllipsoidCurveImpl.h | 3 + ...siumWebMapTileServiceRasterOverlayImpl.cpp | 6 +- .../Runtime/src/CesiumWgs84EllipsoidImpl.cpp | 57 +++++---------- .../src/UnityPrepareRendererResources.cpp | 3 +- native~/Runtime/src/UnityTilesetExternals.cpp | 10 ++- native~/Runtime/src/UnityTilesetExternals.h | 3 +- native~/extern/cesium-native | 2 +- 28 files changed, 443 insertions(+), 84 deletions(-) create mode 100644 Runtime/CesiumEllipsoid.cs create mode 100644 Runtime/CesiumEllipsoid.cs.meta create mode 100644 native~/Runtime/src/CesiumEllipsoidFunctions.cpp create mode 100644 native~/Runtime/src/CesiumEllipsoidFunctions.h create mode 100644 native~/Runtime/src/CesiumEllipsoidImpl.cpp create mode 100644 native~/Runtime/src/CesiumEllipsoidImpl.h diff --git a/Editor/CesiumGeoreferenceEditor.cs b/Editor/CesiumGeoreferenceEditor.cs index b216095c..73b8fb3f 100644 --- a/Editor/CesiumGeoreferenceEditor.cs +++ b/Editor/CesiumGeoreferenceEditor.cs @@ -21,6 +21,7 @@ internal CesiumGeoreferenceOriginAuthority originAuthority } } + private SerializedProperty _ellipsoidOverride; private SerializedProperty _latitude; private SerializedProperty _longitude; private SerializedProperty _height; @@ -35,6 +36,7 @@ private void OnEnable() { this._georeference = (CesiumGeoreference)this.target; + this._ellipsoidOverride = this.serializedObject.FindProperty("_ellipsoidOverride"); this._originAuthority = this.serializedObject.FindProperty("_originAuthority"); @@ -56,6 +58,8 @@ public override void OnInspectorGUI() DrawInspectorButtons(); EditorGUILayout.Space(5); + this.DrawEllipsoidOverrideProperty(); + EditorGUILayout.Space(5); this.DrawScaleProperty(); EditorGUILayout.Space(5); this.DrawOriginAuthorityProperty(); @@ -104,6 +108,16 @@ private void DrawInspectorButtons() EditorGUI.EndDisabledGroup(); } + private void DrawEllipsoidOverrideProperty() + { + GUIContent ellipsoidOverrideContent = new GUIContent( + "Ellipsoid Override", + "The ellipsoid definition to use for this tileset. If this is left blank, " + + "the ellipsoid specified by the tileset is used, or WGS84 if the tileset " + + "doesn't list an ellipsoid to use."); + EditorGUILayout.PropertyField(this._ellipsoidOverride, ellipsoidOverrideContent); + } + private void DrawScaleProperty() { GUIContent scaleContent = new GUIContent( diff --git a/Runtime/CesiumEllipsoid.cs b/Runtime/CesiumEllipsoid.cs new file mode 100644 index 00000000..fd8bac04 --- /dev/null +++ b/Runtime/CesiumEllipsoid.cs @@ -0,0 +1,48 @@ +using Reinterop; +using Unity.Mathematics; +using UnityEngine; +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; + + +namespace CesiumForUnity +{ + [ReinteropNativeImplementation("CesiumForUnityNative::CesiumEllipsoidImpl", "CesiumEllipsoidImpl.h")] + [IconAttribute("Packages/com.cesium.unity/Editor/Resources/Cesium-24x24.png")] + [CreateAssetMenu(menuName = "Cesium/Ellipsoid")] + public partial class CesiumEllipsoid : ScriptableObject + { + public static CesiumEllipsoid WGS84 + { + get + { + if (_cachedWgs84 == null) + { + _cachedWgs84 = ScriptableObject.CreateInstance(); + _cachedWgs84.SetRadii(CesiumWgs84Ellipsoid.GetRadii()); + } + return _cachedWgs84; + } + } + + private static CesiumEllipsoid _cachedWgs84; + + [SerializeField] + private double3 _radii = new double3(1.0, 1.0, 1.0); + + public double3 radii + { + get => _radii; + set => _radii = value; + } + + private partial double3 GetRadii(); + private partial void SetRadii(double3 newRadii); + private partial double3? ScaleToGeodeticSurface(double3 ellipsoidCenteredEllipsoidFixed); + private partial double3 GeodeticSurfaceNormal(double3 ellipsoidCenteredEllipsoidFixed); + private partial double3 LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(double3 longitudeLatitudeHeight); + private partial double3 EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(double3 ellipsoidCenteredEllipsoidFixed); + } +} diff --git a/Runtime/CesiumEllipsoid.cs.meta b/Runtime/CesiumEllipsoid.cs.meta new file mode 100644 index 00000000..4194a092 --- /dev/null +++ b/Runtime/CesiumEllipsoid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b804adc3b6f529547be7580b9ddc8d86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/CesiumFlyToController.cs b/Runtime/CesiumFlyToController.cs index 399842f8..dbea7a53 100644 --- a/Runtime/CesiumFlyToController.cs +++ b/Runtime/CesiumFlyToController.cs @@ -361,7 +361,10 @@ private void ComputeFlightPath( this._destinationRotation = Quaternion.Euler(pitchAtDestination, yawAtDestination, 0.0f); this._destinationECEF = destinationECEF; - this._flightPath = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(sourceECEF, destinationECEF); + this._flightPath = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates( + this._georeference.ellipsoid, + sourceECEF, + destinationECEF); this._flightPathLength = math.length(sourceECEF - destinationECEF); this._maxHeight = 0.0; diff --git a/Runtime/CesiumGeoreference.cs b/Runtime/CesiumGeoreference.cs index 644b60aa..019fd54d 100644 --- a/Runtime/CesiumGeoreference.cs +++ b/Runtime/CesiumGeoreference.cs @@ -65,6 +65,8 @@ public enum CesiumGeoreferenceOriginAuthority public partial class CesiumGeoreference : MonoBehaviour { #region Fields + [SerializeField] + private CesiumEllipsoid _ellipsoidOverride = null; [SerializeField] private CesiumGeoreferenceOriginAuthority _originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight; @@ -106,6 +108,9 @@ public partial class CesiumGeoreference : MonoBehaviour [NonSerialized] private HashSet _globeAnchors = new HashSet(); + [NonSerialized] + private CesiumEllipsoid _ellipsoid = null; + #endregion /// @@ -254,6 +259,23 @@ public double4x4 ecefToLocalMatrix } } + public CesiumEllipsoid ellipsoid + { + get + { + if (this._ellipsoid == null) + { + this._ellipsoid = this._ellipsoidOverride ?? CesiumEllipsoid.WGS84; + } + + return this._ellipsoid; + } + set + { + this._ellipsoid = value; + } + } + /// /// An event raised when the georeference changes. /// diff --git a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs index d4ed6ac4..3fb45744 100644 --- a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs +++ b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs @@ -22,10 +22,10 @@ public partial class CesiumSimplePlanarEllipsoidCurve /// A if a curve can successfully be /// created between the two points, or null otherwise. /// - public static CesiumSimplePlanarEllipsoidCurve FromEarthCenteredEarthFixedCoordinates(double3 sourceEcef, double3 destinationEcef) + public static CesiumSimplePlanarEllipsoidCurve FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef) { CesiumSimplePlanarEllipsoidCurve curve = new CesiumSimplePlanarEllipsoidCurve(); - if (!curve.CreateFromEarthCenteredEarthFixedCoordinates(sourceEcef, destinationEcef)) + if (!curve.CreateFromEarthCenteredEarthFixedCoordinates(ellipsoid, sourceEcef, destinationEcef)) { return null; } @@ -43,10 +43,10 @@ public static CesiumSimplePlanarEllipsoidCurve FromEarthCenteredEarthFixedCoordi /// A if a curve can successfully be /// created between the two points, or null otherwise. /// - public static CesiumSimplePlanarEllipsoidCurve FromLongituteLatitudeHeight(double3 sourceLlh, double3 destinationLlh) + public static CesiumSimplePlanarEllipsoidCurve FromLongituteLatitudeHeight(CesiumEllipsoid ellipsoid, double3 sourceLlh, double3 destinationLlh) { CesiumSimplePlanarEllipsoidCurve curve = new CesiumSimplePlanarEllipsoidCurve(); - if (!curve.CreateFromLongitudeLatitudeHeight(sourceLlh, destinationLlh)) + if (!curve.CreateFromLongitudeLatitudeHeight(ellipsoid, sourceLlh, destinationLlh)) { return null; } @@ -70,8 +70,8 @@ public static CesiumSimplePlanarEllipsoidCurve FromLongituteLatitudeHeight(doubl /// The position of the given point on this curve in Earth-Centered, Earth-Fixed coordinates. public partial double3 GetPosition(double percentage, double additionalHeight = 0.0); - private partial bool CreateFromEarthCenteredEarthFixedCoordinates(double3 sourceEcef, double3 destinationEcef); - private partial bool CreateFromLongitudeLatitudeHeight(double3 sourceLlh, double3 destinationLlh); + private partial bool CreateFromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef); + private partial bool CreateFromLongitudeLatitudeHeight(CesiumEllipsoid ellipsoid, double3 sourceLlh, double3 destinationLlh); private CesiumSimplePlanarEllipsoidCurve() { diff --git a/Runtime/ConfigureReinterop.cs b/Runtime/ConfigureReinterop.cs index 46eafc39..59d284ab 100644 --- a/Runtime/ConfigureReinterop.cs +++ b/Runtime/ConfigureReinterop.cs @@ -517,7 +517,13 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails CesiumGlobeAnchor globeAnchor = globeAnchors[globeAnchors.Length - 1]; globeAnchor.positionGlobeFixed = globeAnchor.positionGlobeFixed; - CesiumSimplePlanarEllipsoidCurve planarEllipsoidCurve = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(new double3(0, 0, 0), new double3(0, 0, 0)); + CesiumSimplePlanarEllipsoidCurve planarEllipsoidCurve = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates( + CesiumEllipsoid.WGS84, + new double3(0, 0, 0), + new double3(0, 0, 0)); + CesiumEllipsoid ellipsoid = CesiumEllipsoid.WGS84; + ellipsoid.radii = new double3(0.0, 0.0, 0.0); + georeference.ellipsoid = ellipsoid; globeAnchor = go.AddComponent(); globeAnchor.detectTransformChanges = globeAnchor.detectTransformChanges; @@ -806,7 +812,7 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails primitiveFeatures = hitInfo.transform.GetComponent(); int triangleIndex = hitInfo.triangleIndex; Vector3 hitPoint = hitInfo.point; - + Vector2 textureCoordinate = new Vector2(); textureCoordinate.x = textureCoordinate.y; hitPoint = m2.MultiplyPoint3x4(hitPoint); diff --git a/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs b/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs index f58cae16..6ff3cd06 100644 --- a/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs +++ b/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs @@ -21,7 +21,7 @@ private double3 RelativeToAbsoluteEpsilon(double3 left, double3 right, double re public IEnumerator StartAndEndOfPathAreIdenticalToInput() { CesiumSimplePlanarEllipsoidCurve flightPath = - CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(_philadelphiaEcef, _tokyoEcef); + CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); Assert.IsNotNull(flightPath); double3 startPosition = flightPath.GetPosition(0.0); @@ -43,7 +43,7 @@ public IEnumerator StartAndEndOfPathAreIdenticalToInput() public IEnumerator ShouldCalculateMidpointCorrectly() { CesiumSimplePlanarEllipsoidCurve flightPath = - CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(_philadelphiaEcef, _tokyoEcef); + CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); Assert.IsNotNull(flightPath); double3 expectedResult = new double3( diff --git a/native~/Runtime/src/CameraManager.cpp b/native~/Runtime/src/CameraManager.cpp index 586eaada..035b4cb1 100644 --- a/native~/Runtime/src/CameraManager.cpp +++ b/native~/Runtime/src/CameraManager.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,7 @@ namespace CesiumForUnityNative { namespace { ViewState unityCameraToViewState( + const CesiumGeoreference& georeference, const LocalHorizontalCoordinateSystem* pCoordinateSystem, const glm::dmat4& unityWorldToTileset, Camera& camera) { @@ -71,13 +73,19 @@ ViewState unityCameraToViewState( double horizontalFOV = 2 * glm::atan(camera.aspect() * glm::tan(verticalFOV * 0.5)); + const CesiumGeospatial::Ellipsoid& ellipsoid = + georeference != nullptr + ? georeference.ellipsoid().NativeImplementation().GetEllipsoid() + : CesiumGeospatial::Ellipsoid::WGS84; + return ViewState::create( cameraPosition, glm::normalize(cameraDirection), glm::normalize(cameraUp), glm::dvec2(camera.pixelWidth(), camera.pixelHeight()), horizontalFOV, - verticalFOV); + verticalFOV, + ellipsoid); } } // namespace @@ -100,8 +108,11 @@ std::vector CameraManager::getAllCameras(const GameObject& context) { std::vector result; Camera camera = Camera::main(); if (camera != nullptr) { - result.emplace_back( - unityCameraToViewState(pCoordinateSystem, unityWorldToTileset, camera)); + result.emplace_back(unityCameraToViewState( + georeferenceComponent, + pCoordinateSystem, + unityWorldToTileset, + camera)); } #if UNITY_EDITOR @@ -111,6 +122,7 @@ std::vector CameraManager::getAllCameras(const GameObject& context) { Camera editorCamera = lastActiveEditorView.camera(); if (editorCamera != nullptr) { result.emplace_back(unityCameraToViewState( + georeferenceComponent, pCoordinateSystem, unityWorldToTileset, editorCamera)); diff --git a/native~/Runtime/src/Cesium3DTilesetImpl.cpp b/native~/Runtime/src/Cesium3DTilesetImpl.cpp index 7353e5fc..cdbfa41f 100644 --- a/native~/Runtime/src/Cesium3DTilesetImpl.cpp +++ b/native~/Runtime/src/Cesium3DTilesetImpl.cpp @@ -1,6 +1,7 @@ #include "Cesium3DTilesetImpl.h" #include "CameraManager.h" +#include "CesiumEllipsoidImpl.h" #include "CesiumIonServerHelper.h" #include "UnityPrepareRendererResources.h" #include "UnityTileExcluderAdaptor.h" @@ -11,6 +12,7 @@ #include #include +#include #include #include #include @@ -325,11 +327,13 @@ void Cesium3DTilesetImpl::FocusTileset( const glm::dmat4& ecefToUnityWorld = georeferenceCrs.getEcefToLocalTransformation(); + const CesiumGeospatial::Ellipsoid& ellipsoid = + georeferenceComponent.ellipsoid().NativeImplementation().GetEllipsoid(); + const BoundingVolume& boundingVolume = this->_pTileset->getRootTile()->getBoundingVolume(); - glm::dvec3 ecefCameraPosition = std::visit( - CalculateECEFCameraPosition{CesiumGeospatial::Ellipsoid::WGS84}, - boundingVolume); + glm::dvec3 ecefCameraPosition = + std::visit(CalculateECEFCameraPosition{ellipsoid}, boundingVolume); glm::dvec3 unityCameraPosition = glm::dvec3(ecefToUnityWorld * glm::dvec4(ecefCameraPosition, 1.0)); @@ -469,6 +473,13 @@ void Cesium3DTilesetImpl::LoadTileset( options.mainThreadLoadingTimeLimit = 5.0; options.tileCacheUnloadTimeLimit = 5.0; + DotNet::CesiumForUnity::CesiumGeoreference georeferenceComponent = + tileset.gameObject() + .GetComponentInParent(); + + options.ellipsoid = + georeferenceComponent.ellipsoid().NativeImplementation().GetEllipsoid(); + TilesetContentOptions contentOptions{}; contentOptions.generateMissingNormalsSmooth = tileset.generateSmoothNormals(); @@ -552,7 +563,7 @@ void Cesium3DTilesetImpl::LoadTileset( ionAssetEndpointUrl += '/'; this->_pTileset = std::make_unique( - createTilesetExternals(tileset), + createTilesetExternals(tileset, options.ellipsoid.value_or(CesiumGeospatial::Ellipsoid::WGS84)), tileset.ionAssetID(), ionAccessToken.ToStlString(), options, @@ -563,7 +574,7 @@ void Cesium3DTilesetImpl::LoadTileset( } } else { this->_pTileset = std::make_unique( - createTilesetExternals(tileset), + createTilesetExternals(tileset, options.ellipsoid.value_or(CesiumGeospatial::Ellipsoid::WGS84)), tileset.url().ToStlString(), options); } diff --git a/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp b/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp index 436cc15f..0a0e1f27 100644 --- a/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp +++ b/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp @@ -81,7 +81,7 @@ void CesiumBingMapsRasterOverlayImpl::AddToTileset( overlay.bingMapsKey().ToStlString(), mapStyle, "", - CesiumGeospatial::Ellipsoid::WGS84, + tileset.NativeImplementation().getTileset()->getEllipsoid(), options); pTileset->getOverlays().add(this->_pOverlay); diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.cpp b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp new file mode 100644 index 00000000..ab1857d4 --- /dev/null +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp @@ -0,0 +1,70 @@ +#include "CesiumEllipsoidFunctions.h" + +#include + +using namespace DotNet::Unity::Mathematics; +using namespace CesiumGeospatial; +using namespace CesiumUtility; + +double3 CesiumEllipsoidFunctions::GetRadii( + const CesiumGeospatial::Ellipsoid& ellipsoid) { + const glm::dvec3& radii = ellipsoid.getRadii(); + return double3{radii.x, radii.y, radii.z}; +} + +std::optional CesiumEllipsoidFunctions::ScaleToGeodeticSurface( + const CesiumGeospatial::Ellipsoid& ellipsoid, + double3 earthCenteredEarthFixed) { + auto result = ellipsoid.scaleToGeodeticSurface(glm::dvec3( + earthCenteredEarthFixed.x, + earthCenteredEarthFixed.y, + earthCenteredEarthFixed.z)); + if (result) { + return double3{result->x, result->y, result->z}; + } + + return std::nullopt; +} + +DotNet::Unity::Mathematics::double3 +CesiumEllipsoidFunctions::GeodeticSurfaceNormal( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed) { + glm::dvec3 result = ellipsoid.geodeticSurfaceNormal(glm::dvec3( + earthCenteredEarthFixed.x, + earthCenteredEarthFixed.y, + earthCenteredEarthFixed.z)); + + return double3{result.x, result.y, result.z}; +} + +DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight) { + glm::dvec3 cartesian = + ellipsoid.cartographicToCartesian(Cartographic::fromDegrees( + longitudeLatitudeHeight.x, + longitudeLatitudeHeight.y, + longitudeLatitudeHeight.z)); + return double3{cartesian.x, cartesian.y, cartesian.z}; +} + +DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed) { + std::optional result = + ellipsoid.cartesianToCartographic(glm::dvec3( + earthCenteredEarthFixed.x, + earthCenteredEarthFixed.y, + earthCenteredEarthFixed.z)); + if (result) { + return double3{ + Math::radiansToDegrees(result->longitude), + Math::radiansToDegrees(result->latitude), + result->height}; + } else { + return double3{0.0, 0.0, 0.0}; + } +} diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.h b/native~/Runtime/src/CesiumEllipsoidFunctions.h new file mode 100644 index 00000000..eca4c5d2 --- /dev/null +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include + +class CesiumEllipsoidFunctions { +public: + static DotNet::Unity::Mathematics::double3 GetRadii(const CesiumGeospatial::Ellipsoid& ellipsoid); + static std::optional + ScaleToGeodeticSurface( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed); + static DotNet::Unity::Mathematics::double3 GeodeticSurfaceNormal( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed); + static DotNet::Unity::Mathematics::double3 + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight); + static DotNet::Unity::Mathematics::double3 + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed); +}; diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.cpp b/native~/Runtime/src/CesiumEllipsoidImpl.cpp new file mode 100644 index 00000000..878fe436 --- /dev/null +++ b/native~/Runtime/src/CesiumEllipsoidImpl.cpp @@ -0,0 +1,69 @@ +#include "CesiumEllipsoidImpl.h" + +#include "CesiumEllipsoidFunctions.h" + +#include +#include + +using namespace DotNet::Unity::Mathematics; +using namespace DotNet::CesiumForUnity; + +CesiumForUnityNative::CesiumEllipsoidImpl::CesiumEllipsoidImpl( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid) + : _ellipsoid( + unityEllipsoid.radii().x, + unityEllipsoid.radii().y, + unityEllipsoid.radii().z) {} + +CesiumForUnityNative::CesiumEllipsoidImpl::~CesiumEllipsoidImpl() {} + +DotNet::Unity::Mathematics::double3 +CesiumForUnityNative::CesiumEllipsoidImpl::GetRadii( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid) { + return CesiumEllipsoidFunctions::GetRadii(this->_ellipsoid); +} + +void CesiumForUnityNative::CesiumEllipsoidImpl::SetRadii( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& newRadii) { + this->_ellipsoid = + CesiumGeospatial::Ellipsoid(newRadii.x, newRadii.y, newRadii.z); +} + +std::optional +CesiumForUnityNative::CesiumEllipsoidImpl::ScaleToGeodeticSurface( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + return CesiumEllipsoidFunctions::ScaleToGeodeticSurface( + this->_ellipsoid, + ellipsoidCenteredEllipsoidFixed); +} + +DotNet::Unity::Mathematics::double3 +CesiumForUnityNative::CesiumEllipsoidImpl::GeodeticSurfaceNormal( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + return CesiumEllipsoidFunctions::GeodeticSurfaceNormal( + this->_ellipsoid, + ellipsoidCenteredEllipsoidFixed); +} + +DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& longitudeLatitudeHeight) { + return CesiumEllipsoidFunctions:: + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + this->_ellipsoid, + longitudeLatitudeHeight); +} + +DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + return CesiumEllipsoidFunctions:: + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + this->_ellipsoid, + ellipsoidCenteredEllipsoidFixed); +} diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.h b/native~/Runtime/src/CesiumEllipsoidImpl.h new file mode 100644 index 00000000..9cfe84bc --- /dev/null +++ b/native~/Runtime/src/CesiumEllipsoidImpl.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +#include + +namespace DotNet::CesiumForUnity { +class CesiumEllipsoid; +} // namespace DotNet::CesiumForUnity + +namespace CesiumForUnityNative { + +class CesiumEllipsoidImpl { +public: + CesiumEllipsoidImpl( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid); + ~CesiumEllipsoidImpl(); + + DotNet::Unity::Mathematics::double3 + GetRadii(const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid); + + void SetRadii( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& newRadii); + + std::optional ScaleToGeodeticSurface( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + + DotNet::Unity::Mathematics::double3 GeodeticSurfaceNormal( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + + DotNet::Unity::Mathematics::double3 + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& longitudeLatitudeHeight); + + DotNet::Unity::Mathematics::double3 + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, + const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + + const CesiumGeospatial::Ellipsoid& GetEllipsoid() const { + return this->_ellipsoid; + } + +private: + CesiumGeospatial::Ellipsoid _ellipsoid; +}; + +} // namespace CesiumForUnityNative diff --git a/native~/Runtime/src/CesiumFeaturesMetadataUtility.cpp b/native~/Runtime/src/CesiumFeaturesMetadataUtility.cpp index 0b993307..a07083ac 100644 --- a/native~/Runtime/src/CesiumFeaturesMetadataUtility.cpp +++ b/native~/Runtime/src/CesiumFeaturesMetadataUtility.cpp @@ -73,7 +73,7 @@ CesiumFeaturesMetadataUtility::addPrimitiveFeatures( CesiumForUnity::CesiumFeatureIdSet featureIdSet = featureIdSets[i]; featureIdSet.label(System::String(gltfFeatureId.label.value_or(""))); featureIdSet.nullFeatureId(gltfFeatureId.nullFeatureId.value_or(-1)); - featureIdSet.propertyTableIndex(gltfFeatureId.propertyTable.value_or(-1)); + featureIdSet.propertyTableIndex(gltfFeatureId.propertyTable); } return primitiveFeatures; diff --git a/native~/Runtime/src/CesiumGeoreferenceImpl.cpp b/native~/Runtime/src/CesiumGeoreferenceImpl.cpp index 842b157b..5a143df1 100644 --- a/native~/Runtime/src/CesiumGeoreferenceImpl.cpp +++ b/native~/Runtime/src/CesiumGeoreferenceImpl.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,8 @@ LocalHorizontalCoordinateSystem createCoordinateSystem( LocalDirection::East, LocalDirection::Up, LocalDirection::North, - 1.0 / georeference.scale()); + 1.0 / georeference.scale(), + georeference.ellipsoid().NativeImplementation().GetEllipsoid()); } else { return LocalHorizontalCoordinateSystem( glm::dvec3( @@ -44,7 +46,8 @@ LocalHorizontalCoordinateSystem createCoordinateSystem( LocalDirection::East, LocalDirection::Up, LocalDirection::North, - 1.0 / georeference.scale()); + 1.0 / georeference.scale(), + georeference.ellipsoid().NativeImplementation().GetEllipsoid()); } } diff --git a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp index ca9f80da..2b36680e 100644 --- a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp +++ b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp @@ -1,11 +1,13 @@ #include "CesiumGlobeAnchorImpl.h" +#include "CesiumEllipsoidImpl.h" #include "UnityTransforms.h" #include #include #include +#include #include #include #include @@ -24,6 +26,15 @@ namespace CesiumForUnityNative { namespace { +const CesiumGeospatial::Ellipsoid& +getAnchorEllipsoid(const ::DotNet::CesiumForUnity::CesiumGlobeAnchor& anchor) { + + anchor.UpdateGeoreferenceIfNecessary(); + DotNet::CesiumForUnity::CesiumGeoreference& georeference = + anchor._georeference(); + return georeference.ellipsoid().NativeImplementation().GetEllipsoid(); +} + GlobeAnchor createOrUpdateNativeGlobeAnchorFromEcef( const ::DotNet::CesiumForUnity::CesiumGlobeAnchor& anchor, const ::DotNet::Unity::Mathematics::double4x4& newLocalToGlobeFixedMatrix) { @@ -37,7 +48,8 @@ GlobeAnchor createOrUpdateNativeGlobeAnchorFromEcef( UnityTransforms::fromUnity(anchor._localToGlobeFixedMatrix())); cppAnchor.setAnchorToFixedTransform( UnityTransforms::fromUnity(newLocalToGlobeFixedMatrix), - anchor.adjustOrientationForGlobeWhenMoving()); + anchor.adjustOrientationForGlobeWhenMoving(), + getAnchorEllipsoid(anchor)); return cppAnchor; } } @@ -61,7 +73,8 @@ GlobeAnchor createOrUpdateNativeGlobeAnchorFromLocal( cppAnchor.setAnchorToLocalTransform( local, newModelToLocal, - anchor.adjustOrientationForGlobeWhenMoving()); + anchor.adjustOrientationForGlobeWhenMoving(), + getAnchorEllipsoid(anchor)); return cppAnchor; } } @@ -105,7 +118,9 @@ void updateAnchorFromCpp( } } -LocalHorizontalCoordinateSystem createEastUpNorth(const GlobeAnchor& anchor) { +LocalHorizontalCoordinateSystem createEastUpNorth( + const GlobeAnchor& anchor, + const CesiumGeospatial::Ellipsoid& ellipsoid) { glm::dvec3 ecefPosition; Transforms::computeTranslationRotationScaleFromMatrix( anchor.getAnchorToFixedTransform(), @@ -118,7 +133,8 @@ LocalHorizontalCoordinateSystem createEastUpNorth(const GlobeAnchor& anchor) { LocalDirection::East, LocalDirection::Up, LocalDirection::North, - 1.0); + 1.0, + ellipsoid); } } // namespace @@ -154,7 +170,8 @@ CesiumGlobeAnchorImpl::GetLocalToEastUpNorthRotation( GlobeAnchor cppAnchor( UnityTransforms::fromUnity(anchor._localToGlobeFixedMatrix())); - LocalHorizontalCoordinateSystem eastUpNorth = createEastUpNorth(cppAnchor); + LocalHorizontalCoordinateSystem eastUpNorth = + createEastUpNorth(cppAnchor, getAnchorEllipsoid(anchor)); glm::dmat4 modelToEastUpNorth = cppAnchor.getAnchorToLocalTransform(eastUpNorth); @@ -174,7 +191,8 @@ void CesiumGlobeAnchorImpl::SetLocalToEastUpNorthRotation( GlobeAnchor cppAnchor( UnityTransforms::fromUnity(anchor._localToGlobeFixedMatrix())); - LocalHorizontalCoordinateSystem eastUpNorth = createEastUpNorth(cppAnchor); + LocalHorizontalCoordinateSystem eastUpNorth = + createEastUpNorth(cppAnchor, getAnchorEllipsoid(anchor)); glm::dmat4 modelToEastUpNorth = cppAnchor.getAnchorToLocalTransform(eastUpNorth); @@ -196,7 +214,8 @@ void CesiumGlobeAnchorImpl::SetLocalToEastUpNorthRotation( cppAnchor.setAnchorToLocalTransform( eastUpNorth, newModelToEastUpNorth, - false); + false, + getAnchorEllipsoid(anchor)); updateAnchorFromCpp(anchor, cppAnchor); } diff --git a/native~/Runtime/src/CesiumMetadataImpl.cpp b/native~/Runtime/src/CesiumMetadataImpl.cpp index 2b593ea9..ceae11cb 100644 --- a/native~/Runtime/src/CesiumMetadataImpl.cpp +++ b/native~/Runtime/src/CesiumMetadataImpl.cpp @@ -129,8 +129,8 @@ CesiumForUnityNative::CesiumMetadataImpl::GetFeatures( features.Item(i, feature); const CesiumGltf::FeatureId& featureIdSet = *featureIdAttributes[i]; - if (!featureIdSet.propertyTable || *featureIdSet.propertyTable < 0 || - *featureIdSet.propertyTable >= + if (!featureIdSet.propertyTable || featureIdSet.propertyTable < 0 || + featureIdSet.propertyTable >= static_cast(pModelMetadata->propertyTables.size())) { continue; } diff --git a/native~/Runtime/src/CesiumPolygonRasterOverlayImpl.cpp b/native~/Runtime/src/CesiumPolygonRasterOverlayImpl.cpp index cf8a704a..b82fabcf 100644 --- a/native~/Runtime/src/CesiumPolygonRasterOverlayImpl.cpp +++ b/native~/Runtime/src/CesiumPolygonRasterOverlayImpl.cpp @@ -99,12 +99,14 @@ void CesiumPolygonRasterOverlayImpl::AddToTileset( nativePolygons.emplace_back(std::move(nativePolygon)); } + const CesiumGeospatial::Ellipsoid& ellipsoid = pTileset->getEllipsoid(); + this->_pOverlay = new RasterizedPolygonsOverlay( overlay.materialKey().ToStlString(), nativePolygons, overlay.invertSelection(), - CesiumGeospatial::Ellipsoid::WGS84, - CesiumGeospatial::GeographicProjection(), + ellipsoid, + CesiumGeospatial::GeographicProjection(ellipsoid), options); pTileset->getOverlays().add(this->_pOverlay); diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp index d2e6b606..f129aea7 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp @@ -17,11 +17,12 @@ CesiumSimplePlanarEllipsoidCurveImpl::~CesiumSimplePlanarEllipsoidCurveImpl() {} bool CesiumSimplePlanarEllipsoidCurveImpl:: CreateFromEarthCenteredEarthFixedCoordinates( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, + const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceEcef, const DotNet::Unity::Mathematics::double3 destinationEcef) { this->_curve = SimplePlanarEllipsoidCurve::fromEarthCenteredEarthFixedCoordinates( - Ellipsoid::WGS84, + ellipsoid.NativeImplementation().GetEllipsoid(), glm::dvec3(sourceEcef.x, sourceEcef.y, sourceEcef.z), glm::dvec3(destinationEcef.x, destinationEcef.y, destinationEcef.z)); @@ -30,10 +31,11 @@ bool CesiumSimplePlanarEllipsoidCurveImpl:: bool CesiumSimplePlanarEllipsoidCurveImpl::CreateFromLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, + const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceLlh, const DotNet::Unity::Mathematics::double3 destinationLlh) { this->_curve = SimplePlanarEllipsoidCurve::fromLongitudeLatitudeHeight( - Ellipsoid::WGS84, + ellipsoid.NativeImplementation().GetEllipsoid(), Cartographic(sourceLlh.x, sourceLlh.y, sourceLlh.z), Cartographic(destinationLlh.x, destinationLlh.y, destinationLlh.z)); diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h index 8663c82b..d519e9c0 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h @@ -3,6 +3,7 @@ #include #include +#include #include @@ -24,11 +25,13 @@ class CesiumSimplePlanarEllipsoidCurveImpl { bool CreateFromEarthCenteredEarthFixedCoordinates( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, + const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceEcef, const DotNet::Unity::Mathematics::double3 destinationEcef); bool CreateFromLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, + const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceLlh, const DotNet::Unity::Mathematics::double3 destinationLlh); diff --git a/native~/Runtime/src/CesiumWebMapTileServiceRasterOverlayImpl.cpp b/native~/Runtime/src/CesiumWebMapTileServiceRasterOverlayImpl.cpp index dd2e7f4b..88a99548 100644 --- a/native~/Runtime/src/CesiumWebMapTileServiceRasterOverlayImpl.cpp +++ b/native~/Runtime/src/CesiumWebMapTileServiceRasterOverlayImpl.cpp @@ -51,6 +51,8 @@ void CesiumWebMapTileServiceRasterOverlayImpl::AddToTileset( return; } + const CesiumGeospatial::Ellipsoid& ellipsoid = pTileset->getEllipsoid(); + WebMapTileServiceRasterOverlayOptions wmtsOptions; wmtsOptions.format = overlay.format().ToStlString(); wmtsOptions.layer = overlay.layer().ToStlString(); @@ -68,9 +70,9 @@ void CesiumWebMapTileServiceRasterOverlayImpl::AddToTileset( if (overlay.projection() == CesiumWebMapTileServiceRasterOverlayProjection::Geographic) { - wmtsOptions.projection = CesiumGeospatial::GeographicProjection(); + wmtsOptions.projection = CesiumGeospatial::GeographicProjection(ellipsoid); } else { - wmtsOptions.projection = CesiumGeospatial::WebMercatorProjection(); + wmtsOptions.projection = CesiumGeospatial::WebMercatorProjection(ellipsoid); } if (overlay.specifyTilingScheme()) { diff --git a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp index f06aef3a..1f1ace1c 100644 --- a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp @@ -1,5 +1,7 @@ #include "CesiumWgs84EllipsoidImpl.h" +#include "CesiumEllipsoidFunctions.h" + #include #include @@ -11,64 +13,39 @@ using namespace DotNet::Unity::Mathematics; namespace CesiumForUnityNative { double3 CesiumWgs84EllipsoidImpl::GetRadii() { - const glm::dvec3 radii = Ellipsoid::WGS84.getRadii(); - return double3{radii.x, radii.y, radii.z}; + return CesiumEllipsoidFunctions::GetRadii(Ellipsoid::WGS84); } std::optional CesiumWgs84EllipsoidImpl::ScaleToGeodeticSurface( double3 earthCenteredEarthFixed) { - const glm::dvec3 cartesian( - earthCenteredEarthFixed.x, - earthCenteredEarthFixed.y, - earthCenteredEarthFixed.z); - - auto result = Ellipsoid::WGS84.scaleToGeodeticSurface(cartesian); - if (result) { - return double3{result->x, result->y, result->z}; - } - - return std::nullopt; + return CesiumEllipsoidFunctions::ScaleToGeodeticSurface( + Ellipsoid::WGS84, + earthCenteredEarthFixed); } double3 CesiumWgs84EllipsoidImpl::GeodeticSurfaceNormal( double3 earthCenteredEarthFixed) { - const glm::dvec3 cartesian( - earthCenteredEarthFixed.x, - earthCenteredEarthFixed.y, - earthCenteredEarthFixed.z); - - glm::dvec3 result = Ellipsoid::WGS84.geodeticSurfaceNormal(cartesian); - - return double3{result.x, result.y, result.z}; + return CesiumEllipsoidFunctions::GeodeticSurfaceNormal( + Ellipsoid::WGS84, + earthCenteredEarthFixed); } double3 CesiumWgs84EllipsoidImpl::LongitudeLatitudeHeightToEarthCenteredEarthFixed( double3 longitudeLatitudeHeight) { - glm::dvec3 cartesian = - Ellipsoid::WGS84.cartographicToCartesian(Cartographic::fromDegrees( - longitudeLatitudeHeight.x, - longitudeLatitudeHeight.y, - longitudeLatitudeHeight.z)); - return double3{cartesian.x, cartesian.y, cartesian.z}; + return CesiumEllipsoidFunctions:: + LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + Ellipsoid::WGS84, + longitudeLatitudeHeight); } double3 CesiumWgs84EllipsoidImpl::EarthCenteredEarthFixedToLongitudeLatitudeHeight( double3 earthCenteredEarthFixed) { - std::optional result = - Ellipsoid::WGS84.cartesianToCartographic(glm::dvec3( - earthCenteredEarthFixed.x, - earthCenteredEarthFixed.y, - earthCenteredEarthFixed.z)); - if (result) { - return double3{ - Math::radiansToDegrees(result->longitude), - Math::radiansToDegrees(result->latitude), - result->height}; - } else { - return double3{0.0, 0.0, 0.0}; - } + return CesiumEllipsoidFunctions:: + EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + Ellipsoid::WGS84, + earthCenteredEarthFixed); } } // namespace CesiumForUnityNative diff --git a/native~/Runtime/src/UnityPrepareRendererResources.cpp b/native~/Runtime/src/UnityPrepareRendererResources.cpp index 34cdbadf..d176f1f0 100644 --- a/native~/Runtime/src/UnityPrepareRendererResources.cpp +++ b/native~/Runtime/src/UnityPrepareRendererResources.cpp @@ -1354,7 +1354,8 @@ void* UnityPrepareRendererResources::prepareInMainThread( glm::dmat4 tileTransform = tile.getTransform(); tileTransform = GltfUtilities::applyRtcCenter(model, tileTransform); - tileTransform = GltfUtilities::applyGltfUpAxisTransform(model, tileTransform); + tileTransform = + GltfUtilities::applyGltfUpAxisTransform(model, tileTransform); DotNet::CesiumForUnity::CesiumGeoreference georeferenceComponent = this->_tilesetGameObject diff --git a/native~/Runtime/src/UnityTilesetExternals.cpp b/native~/Runtime/src/UnityTilesetExternals.cpp index 45001fb8..c9b4d8ba 100644 --- a/native~/Runtime/src/UnityTilesetExternals.cpp +++ b/native~/Runtime/src/UnityTilesetExternals.cpp @@ -4,6 +4,7 @@ #include "UnityPrepareRendererResources.h" #include "UnityTaskProcessor.h" +#include #include #include #include @@ -90,14 +91,17 @@ getOrCreateCreditSystem(const CesiumForUnity::Cesium3DTileset& tileset) { return pCreditSystem; } -Cesium3DTilesSelection::TilesetExternals -createTilesetExternals(const CesiumForUnity::Cesium3DTileset& tileset) { - return TilesetExternals{ +Cesium3DTilesSelection::TilesetExternals createTilesetExternals( + const CesiumForUnity::Cesium3DTileset& tileset, + const CesiumGeospatial::Ellipsoid& ellipsoid) { + TilesetExternals externals = TilesetExternals{ getAssetAccessor(), std::make_shared(tileset.gameObject()), AsyncSystem(getTaskProcessor()), getOrCreateCreditSystem(tileset), spdlog::default_logger()}; + externals.pEllipsoid = std::make_shared(ellipsoid); + return externals; } } // namespace CesiumForUnityNative diff --git a/native~/Runtime/src/UnityTilesetExternals.h b/native~/Runtime/src/UnityTilesetExternals.h index 01bd5bd4..bb9a5e4a 100644 --- a/native~/Runtime/src/UnityTilesetExternals.h +++ b/native~/Runtime/src/UnityTilesetExternals.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -36,6 +37,6 @@ const std::shared_ptr& getOrCreateCreditSystem(const DotNet::CesiumForUnity::Cesium3DTileset& tileset); Cesium3DTilesSelection::TilesetExternals -createTilesetExternals(const DotNet::CesiumForUnity::Cesium3DTileset& tileset); +createTilesetExternals(const DotNet::CesiumForUnity::Cesium3DTileset& tileset, const CesiumGeospatial::Ellipsoid& ellipsoid); } // namespace CesiumForUnityNative diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index cd67f6f4..f332464b 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit cd67f6f4094324414fd416fec8d5c837cdc75287 +Subproject commit f332464b30adf1248860c8c966e999c6ed736252 From d7e1283869760d4434845c999456674d2a1721f1 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Tue, 11 Jun 2024 13:59:35 -0400 Subject: [PATCH 02/14] Update cesium-native, handle ellipsoid property change. --- Editor/CesiumGeoreferenceEditor.cs | 5 +++++ Runtime/CesiumGeoreference.cs | 13 +++++++++++++ WGS84.asset | 18 ++++++++++++++++++ WGS84.asset.meta | 8 ++++++++ native~/Runtime/src/Cesium3DTilesetImpl.cpp | 4 ++-- native~/Runtime/src/UnityTilesetExternals.cpp | 1 - native~/extern/cesium-native | 2 +- 7 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 WGS84.asset create mode 100644 WGS84.asset.meta diff --git a/Editor/CesiumGeoreferenceEditor.cs b/Editor/CesiumGeoreferenceEditor.cs index 73b8fb3f..f2f3ce2f 100644 --- a/Editor/CesiumGeoreferenceEditor.cs +++ b/Editor/CesiumGeoreferenceEditor.cs @@ -115,7 +115,12 @@ private void DrawEllipsoidOverrideProperty() "The ellipsoid definition to use for this tileset. If this is left blank, " + "the ellipsoid specified by the tileset is used, or WGS84 if the tileset " + "doesn't list an ellipsoid to use."); + EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(this._ellipsoidOverride, ellipsoidOverrideContent); + if(EditorGUI.EndChangeCheck()) + { + this._georeference.ReloadEllipsoid(); + } } private void DrawScaleProperty() diff --git a/Runtime/CesiumGeoreference.cs b/Runtime/CesiumGeoreference.cs index 019fd54d..864bf578 100644 --- a/Runtime/CesiumGeoreference.cs +++ b/Runtime/CesiumGeoreference.cs @@ -378,6 +378,19 @@ public void Initialize() } } + /// + /// Called when the ellipsoid override property has changed. + /// + public void ReloadEllipsoid() + { + this._ellipsoid = this._ellipsoidOverride ?? CesiumEllipsoid.WGS84; + Cesium3DTileset[] tilesets = GetComponentsInChildren(); + foreach(var tileset in tilesets) + { + tileset.RecreateTileset(); + } + } + private void UpdateTransformations() { this._localToEcef = this.ComputeLocalToEarthCenteredEarthFixedTransformation(); diff --git a/WGS84.asset b/WGS84.asset new file mode 100644 index 00000000..e2b271c5 --- /dev/null +++ b/WGS84.asset @@ -0,0 +1,18 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b804adc3b6f529547be7580b9ddc8d86, type: 3} + m_Name: WGS84 + m_EditorClassIdentifier: + _radii: + x: 6378137 + y: 6378137 + z: 6356752.314245 diff --git a/WGS84.asset.meta b/WGS84.asset.meta new file mode 100644 index 00000000..1f3537db --- /dev/null +++ b/WGS84.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5db7b2e3ffd57a049aba6b75aa797982 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/native~/Runtime/src/Cesium3DTilesetImpl.cpp b/native~/Runtime/src/Cesium3DTilesetImpl.cpp index cdbfa41f..89b2b11a 100644 --- a/native~/Runtime/src/Cesium3DTilesetImpl.cpp +++ b/native~/Runtime/src/Cesium3DTilesetImpl.cpp @@ -563,7 +563,7 @@ void Cesium3DTilesetImpl::LoadTileset( ionAssetEndpointUrl += '/'; this->_pTileset = std::make_unique( - createTilesetExternals(tileset, options.ellipsoid.value_or(CesiumGeospatial::Ellipsoid::WGS84)), + createTilesetExternals(tileset, options.ellipsoid), tileset.ionAssetID(), ionAccessToken.ToStlString(), options, @@ -574,7 +574,7 @@ void Cesium3DTilesetImpl::LoadTileset( } } else { this->_pTileset = std::make_unique( - createTilesetExternals(tileset, options.ellipsoid.value_or(CesiumGeospatial::Ellipsoid::WGS84)), + createTilesetExternals(tileset, options.ellipsoid), tileset.url().ToStlString(), options); } diff --git a/native~/Runtime/src/UnityTilesetExternals.cpp b/native~/Runtime/src/UnityTilesetExternals.cpp index c9b4d8ba..9ad9cfb1 100644 --- a/native~/Runtime/src/UnityTilesetExternals.cpp +++ b/native~/Runtime/src/UnityTilesetExternals.cpp @@ -100,7 +100,6 @@ Cesium3DTilesSelection::TilesetExternals createTilesetExternals( AsyncSystem(getTaskProcessor()), getOrCreateCreditSystem(tileset), spdlog::default_logger()}; - externals.pEllipsoid = std::make_shared(ellipsoid); return externals; } diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index f332464b..7517ad97 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit f332464b30adf1248860c8c966e999c6ed736252 +Subproject commit 7517ad97dfda905ee058e08c7bd4110a5fba0e2c From 7c24ce72df8bf18e00d8641f3b8f99c607c922a1 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Tue, 11 Jun 2024 14:23:48 -0400 Subject: [PATCH 03/14] Update cesium-native --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 7517ad97..1598c3f8 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 7517ad97dfda905ee058e08c7bd4110a5fba0e2c +Subproject commit 1598c3f863a3ea22f86094476b1192f5f7075c69 From 1ec548ff5f2e2fbab578626aa0c918f29922f406 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Tue, 11 Jun 2024 14:25:31 -0400 Subject: [PATCH 04/14] clang-format --- native~/Runtime/src/Cesium3DTilesetImpl.cpp | 2 +- native~/Runtime/src/CesiumEllipsoidFunctions.h | 6 ++++-- native~/Runtime/src/CesiumEllipsoidImpl.cpp | 9 ++++++--- native~/Runtime/src/CesiumEllipsoidImpl.h | 12 ++++++++---- native~/Runtime/src/CesiumGeoreferenceImpl.cpp | 2 +- .../src/CesiumSimplePlanarEllipsoidCurveImpl.h | 2 +- .../Runtime/src/UnityPrepareRendererResources.cpp | 3 +-- native~/Runtime/src/UnityTilesetExternals.h | 5 +++-- 8 files changed, 25 insertions(+), 16 deletions(-) diff --git a/native~/Runtime/src/Cesium3DTilesetImpl.cpp b/native~/Runtime/src/Cesium3DTilesetImpl.cpp index 89b2b11a..bddd80ea 100644 --- a/native~/Runtime/src/Cesium3DTilesetImpl.cpp +++ b/native~/Runtime/src/Cesium3DTilesetImpl.cpp @@ -12,11 +12,11 @@ #include #include -#include #include #include #include #include +#include #include #include #include diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.h b/native~/Runtime/src/CesiumEllipsoidFunctions.h index eca4c5d2..57631e93 100644 --- a/native~/Runtime/src/CesiumEllipsoidFunctions.h +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.h @@ -1,13 +1,15 @@ #pragma once -#include #include +#include + #include class CesiumEllipsoidFunctions { public: - static DotNet::Unity::Mathematics::double3 GetRadii(const CesiumGeospatial::Ellipsoid& ellipsoid); + static DotNet::Unity::Mathematics::double3 + GetRadii(const CesiumGeospatial::Ellipsoid& ellipsoid); static std::optional ScaleToGeodeticSurface( const CesiumGeospatial::Ellipsoid& ellipsoid, diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.cpp b/native~/Runtime/src/CesiumEllipsoidImpl.cpp index 878fe436..af5994ee 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumEllipsoidImpl.cpp @@ -33,7 +33,8 @@ void CesiumForUnityNative::CesiumEllipsoidImpl::SetRadii( std::optional CesiumForUnityNative::CesiumEllipsoidImpl::ScaleToGeodeticSurface( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed) { return CesiumEllipsoidFunctions::ScaleToGeodeticSurface( this->_ellipsoid, ellipsoidCenteredEllipsoidFixed); @@ -42,7 +43,8 @@ CesiumForUnityNative::CesiumEllipsoidImpl::ScaleToGeodeticSurface( DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl::GeodeticSurfaceNormal( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed) { return CesiumEllipsoidFunctions::GeodeticSurfaceNormal( this->_ellipsoid, ellipsoidCenteredEllipsoidFixed); @@ -61,7 +63,8 @@ DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed) { return CesiumEllipsoidFunctions:: EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( this->_ellipsoid, diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.h b/native~/Runtime/src/CesiumEllipsoidImpl.h index 9cfe84bc..bd0fb053 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.h +++ b/native~/Runtime/src/CesiumEllipsoidImpl.h @@ -1,10 +1,11 @@ #pragma once #include -#include #include +#include + namespace DotNet::CesiumForUnity { class CesiumEllipsoid; } // namespace DotNet::CesiumForUnity @@ -26,11 +27,13 @@ class CesiumEllipsoidImpl { std::optional ScaleToGeodeticSurface( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed); DotNet::Unity::Mathematics::double3 GeodeticSurfaceNormal( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed); DotNet::Unity::Mathematics::double3 LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( @@ -40,7 +43,8 @@ class CesiumEllipsoidImpl { DotNet::Unity::Mathematics::double3 EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, - const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); + const DotNet::Unity::Mathematics::double3& + ellipsoidCenteredEllipsoidFixed); const CesiumGeospatial::Ellipsoid& GetEllipsoid() const { return this->_ellipsoid; diff --git a/native~/Runtime/src/CesiumGeoreferenceImpl.cpp b/native~/Runtime/src/CesiumGeoreferenceImpl.cpp index 5a143df1..192fb80e 100644 --- a/native~/Runtime/src/CesiumGeoreferenceImpl.cpp +++ b/native~/Runtime/src/CesiumGeoreferenceImpl.cpp @@ -5,10 +5,10 @@ #include #include +#include #include #include #include -#include #include #include #include diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h index d519e9c0..4d891f6e 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h @@ -2,8 +2,8 @@ #include -#include #include +#include #include diff --git a/native~/Runtime/src/UnityPrepareRendererResources.cpp b/native~/Runtime/src/UnityPrepareRendererResources.cpp index d176f1f0..34cdbadf 100644 --- a/native~/Runtime/src/UnityPrepareRendererResources.cpp +++ b/native~/Runtime/src/UnityPrepareRendererResources.cpp @@ -1354,8 +1354,7 @@ void* UnityPrepareRendererResources::prepareInMainThread( glm::dmat4 tileTransform = tile.getTransform(); tileTransform = GltfUtilities::applyRtcCenter(model, tileTransform); - tileTransform = - GltfUtilities::applyGltfUpAxisTransform(model, tileTransform); + tileTransform = GltfUtilities::applyGltfUpAxisTransform(model, tileTransform); DotNet::CesiumForUnity::CesiumGeoreference georeferenceComponent = this->_tilesetGameObject diff --git a/native~/Runtime/src/UnityTilesetExternals.h b/native~/Runtime/src/UnityTilesetExternals.h index bb9a5e4a..bf3dfaf9 100644 --- a/native~/Runtime/src/UnityTilesetExternals.h +++ b/native~/Runtime/src/UnityTilesetExternals.h @@ -36,7 +36,8 @@ CesiumAsync::AsyncSystem getAsyncSystem(); const std::shared_ptr& getOrCreateCreditSystem(const DotNet::CesiumForUnity::Cesium3DTileset& tileset); -Cesium3DTilesSelection::TilesetExternals -createTilesetExternals(const DotNet::CesiumForUnity::Cesium3DTileset& tileset, const CesiumGeospatial::Ellipsoid& ellipsoid); +Cesium3DTilesSelection::TilesetExternals createTilesetExternals( + const DotNet::CesiumForUnity::Cesium3DTileset& tileset, + const CesiumGeospatial::Ellipsoid& ellipsoid); } // namespace CesiumForUnityNative From 4e74b1a79b6b34dc0605cd7131720ee463c6ecaa Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Fri, 14 Jun 2024 11:43:24 -0400 Subject: [PATCH 05/14] Update cesium-native --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 1598c3f8..7c01db3b 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 1598c3f863a3ea22f86094476b1192f5f7075c69 +Subproject commit 7c01db3ba781a090932d404499bf491658b9bb42 From b6b635ed19772dac0fe1002243c9ab0e513a843e Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Fri, 14 Jun 2024 16:24:10 -0400 Subject: [PATCH 06/14] Update cesium-native --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 7c01db3b..110ff3b0 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 7c01db3ba781a090932d404499bf491658b9bb42 +Subproject commit 110ff3b00919db6fbe7865af6d35c96c9311653e From 5343c31621484809ca38732cdb1579b9600e2ed4 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Mon, 17 Jun 2024 14:05:25 -0400 Subject: [PATCH 07/14] Fix GlobeAnchor build issue --- native~/Runtime/src/CesiumGlobeAnchorImpl.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp index 2b36680e..7efd88e0 100644 --- a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp +++ b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp @@ -30,9 +30,10 @@ const CesiumGeospatial::Ellipsoid& getAnchorEllipsoid(const ::DotNet::CesiumForUnity::CesiumGlobeAnchor& anchor) { anchor.UpdateGeoreferenceIfNecessary(); - DotNet::CesiumForUnity::CesiumGeoreference& georeference = - anchor._georeference(); - return georeference.ellipsoid().NativeImplementation().GetEllipsoid(); + return anchor._georeference() + .ellipsoid() + .NativeImplementation() + .GetEllipsoid(); } GlobeAnchor createOrUpdateNativeGlobeAnchorFromEcef( From a3d720fee3b34bc46e96e10b4c00b0d4c697515d Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Tue, 18 Jun 2024 14:11:30 -0400 Subject: [PATCH 08/14] Fix remaining WGS84 references, add test. --- Runtime/CesiumCameraController.cs | 4 +- Runtime/CesiumCartographicPolygon.cs | 2 +- Runtime/CesiumEllipsoid.cs | 78 ++++++++++++++++++--- Runtime/CesiumFlyToController.cs | 4 +- Runtime/CesiumGeoreference.cs | 4 +- Runtime/CesiumGlobeAnchor.cs | 4 +- Runtime/CesiumSimplePlanarEllipsoidCurve.cs | 2 +- Runtime/CesiumSubScene.cs | 14 +++- Tests/Comparers.cs | 31 ++++++++ Tests/TestCesiumGlobeAnchor.cs | 34 +++++++++ 10 files changed, 157 insertions(+), 20 deletions(-) diff --git a/Runtime/CesiumCameraController.cs b/Runtime/CesiumCameraController.cs index ee419b16..bd5c5e03 100644 --- a/Runtime/CesiumCameraController.cs +++ b/Runtime/CesiumCameraController.cs @@ -622,7 +622,7 @@ private void Move(Vector3 movementInput) if (this._georeference != null) { double3 positionECEF = this._globeAnchor.positionGlobeFixed; - double3 upECEF = CesiumWgs84Ellipsoid.GeodeticSurfaceNormal(positionECEF); + double3 upECEF = this._georeference.ellipsoid.GeodeticSurfaceNormal(positionECEF); double3 upUnity = this._georeference.TransformEarthCenteredEarthFixedDirectionToUnity(upECEF); @@ -801,7 +801,7 @@ private void UpdateClippingPlanes() if (height >= this._dynamicClippingPlanesMinHeight) { - farClipPlane = height + (float)(2.0 * CesiumWgs84Ellipsoid.GetMaximumRadius()); + farClipPlane = height + (float)(2.0 * this._georeference.ellipsoid.GetMaximumRadius()); farClipPlane = Mathf.Min(farClipPlane, this._maximumFarClipPlane); float farClipRatio = farClipPlane / this._maximumNearToFarRatio; diff --git a/Runtime/CesiumCartographicPolygon.cs b/Runtime/CesiumCartographicPolygon.cs index 13305fc1..1ab917f1 100644 --- a/Runtime/CesiumCartographicPolygon.cs +++ b/Runtime/CesiumCartographicPolygon.cs @@ -138,7 +138,7 @@ internal List GetCartographicPoints(Matrix4x4 worldToTileset) float3 worldPosition = knot.Transform(localToWorld).Position; float3 unityPosition = worldToTileset.MultiplyPoint3x4(worldPosition); double3 ecefPosition = georeference.TransformUnityPositionToEarthCenteredEarthFixed(unityPosition); - double3 cartographicPosition = CesiumWgs84Ellipsoid.EarthCenteredEarthFixedToLongitudeLatitudeHeight(ecefPosition); + double3 cartographicPosition = georeference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(ecefPosition); cartographicPoints.Add(cartographicPosition.xy); } diff --git a/Runtime/CesiumEllipsoid.cs b/Runtime/CesiumEllipsoid.cs index fd8bac04..247809c3 100644 --- a/Runtime/CesiumEllipsoid.cs +++ b/Runtime/CesiumEllipsoid.cs @@ -14,15 +14,19 @@ namespace CesiumForUnity [CreateAssetMenu(menuName = "Cesium/Ellipsoid")] public partial class CesiumEllipsoid : ScriptableObject { + /// + /// Obtain a WGS84 ellipsoid. + /// public static CesiumEllipsoid WGS84 { get { if (_cachedWgs84 == null) { - _cachedWgs84 = ScriptableObject.CreateInstance(); + _cachedWgs84 = CreateInstance(); _cachedWgs84.SetRadii(CesiumWgs84Ellipsoid.GetRadii()); } + return _cachedWgs84; } } @@ -32,17 +36,75 @@ public static CesiumEllipsoid WGS84 [SerializeField] private double3 _radii = new double3(1.0, 1.0, 1.0); - public double3 radii + internal double3 radii { get => _radii; set => _radii = value; } - private partial double3 GetRadii(); - private partial void SetRadii(double3 newRadii); - private partial double3? ScaleToGeodeticSurface(double3 ellipsoidCenteredEllipsoidFixed); - private partial double3 GeodeticSurfaceNormal(double3 ellipsoidCenteredEllipsoidFixed); - private partial double3 LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(double3 longitudeLatitudeHeight); - private partial double3 EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(double3 ellipsoidCenteredEllipsoidFixed); + /// + /// Gets the maximum radius of the ellipsoid in any dimension. + /// + /// The maximum radius of the ellipsoid. + public double GetMaximumRadius() + { + return math.cmax(this.GetRadii()); + } + + /// + /// Gets the minimum radius of the ellipsoid in any dimension. + /// + /// The minimum radius of the ellipsoid. + public double GetMinimumRadius() + { + return math.cmin(this.GetRadii()); + } + + /// + /// Returns the radii of this ellipsoid. + /// + public partial double3 GetRadii(); + + /// + /// Sets the radii of this ellipsoid to the given values. + /// + /// The new (x, y, z) radii of the ellipsoid. + public partial void SetRadii(double3 newRadii); + + /// + /// Scale the given Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) position along the geodetic surface normal + /// so that it is on the surface of the ellipsoid. If the position is at the center of the + /// ellipsoid, the result will be null. + /// + /// The ECEF position in meters. + /// The scaled position, or null if the position is at the center of the ellipsoid. + public partial double3? ScaleToGeodeticSurface(double3 ellipsoidCenteredEllipsoidFixed); + + /// + /// Computes the normal of the plane tangent to the surface of the ellipsoid at the provided + /// Ellipsoid-Centered, Ellipsoid-Fixed position. + /// + /// The ECEF position in meters. + /// The normal at the ECEF position + public partial double3 GeodeticSurfaceNormal(double3 ellipsoidCenteredEllipsoidFixed); + + /// + /// Convert longitude, latitude, and height to Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) coordinates. + /// + /// + /// The longitude (X) and latitude (Y) are in degrees. The height (Z) is in meters above the ellipsoid, + /// and should not be confused with a geoid, orthometric, or mean sea level height. + /// The ECEF coordinates in meters. + public partial double3 LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(double3 longitudeLatitudeHeight); + + /// + /// Convert Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) coordinates to longitude, latitude, and height. + /// + /// The ECEF coordinates in meters. + /// + /// The longitude (X) and latitude (Y) are in degrees. The height (Z) is in meters above the ellipsoid, + /// and should not be confused with a geoid, orthometric, or mean sea level height. + /// + public partial double3 EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(double3 ellipsoidCenteredEllipsoidFixed); } } diff --git a/Runtime/CesiumFlyToController.cs b/Runtime/CesiumFlyToController.cs index dbea7a53..0681a44f 100644 --- a/Runtime/CesiumFlyToController.cs +++ b/Runtime/CesiumFlyToController.cs @@ -486,7 +486,7 @@ public void FlyToLocationLongitudeLatitudeHeight( bool canInterruptByMoving) { double3 destinationECEF = - CesiumWgs84Ellipsoid.LongitudeLatitudeHeightToEarthCenteredEarthFixed(destination); + this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(destination); this.FlyToLocationEarthCenteredEarthFixed( destinationECEF, @@ -525,7 +525,7 @@ public void FlyToLocationLongitudeLatitudeHeight( z = destination.z }; double3 destinationECEF = - CesiumWgs84Ellipsoid.LongitudeLatitudeHeightToEarthCenteredEarthFixed( + this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( destinationCoordinates); this.FlyToLocationEarthCenteredEarthFixed( diff --git a/Runtime/CesiumGeoreference.cs b/Runtime/CesiumGeoreference.cs index 864bf578..2ae60283 100644 --- a/Runtime/CesiumGeoreference.cs +++ b/Runtime/CesiumGeoreference.cs @@ -459,7 +459,7 @@ private void UpdateOtherCoordinates() if (this._originAuthority == CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight) { double3 ecef = - CesiumWgs84Ellipsoid.LongitudeLatitudeHeightToEarthCenteredEarthFixed( + this.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( new double3(this._longitude, this._latitude, this._height)); this._ecefX = ecef.x; this._ecefY = ecef.y; @@ -468,7 +468,7 @@ private void UpdateOtherCoordinates() else if (this._originAuthority == CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed) { double3 llh = - CesiumWgs84Ellipsoid.EarthCenteredEarthFixedToLongitudeLatitudeHeight( + this.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( new double3(this._ecefX, this._ecefY, this._ecefZ)); this._longitude = llh.x; this._latitude = llh.y; diff --git a/Runtime/CesiumGlobeAnchor.cs b/Runtime/CesiumGlobeAnchor.cs index e038206f..35e9ac66 100644 --- a/Runtime/CesiumGlobeAnchor.cs +++ b/Runtime/CesiumGlobeAnchor.cs @@ -182,10 +182,10 @@ public double4x4 localToGlobeFixedMatrix /// public double3 longitudeLatitudeHeight { - get => CesiumWgs84Ellipsoid.EarthCenteredEarthFixedToLongitudeLatitudeHeight(this.positionGlobeFixed); + get => this._georeference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(this.positionGlobeFixed); set { - this.positionGlobeFixed = CesiumWgs84Ellipsoid.LongitudeLatitudeHeightToEarthCenteredEarthFixed(value); + this.positionGlobeFixed = this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(value); } } diff --git a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs index 3fb45744..c17cf953 100644 --- a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs +++ b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs @@ -6,7 +6,7 @@ namespace CesiumForUnity { /// /// Describes a curve that's a section of an ellipse that lies on a plane intersecting the center of the earth and - /// both the source and destination points on a WGS84 ellipsoid. This curve can be sampled at any point along its length. + /// both the source and destination points on an ellipsoid. This curve can be sampled at any point along its length. /// [ReinteropNativeImplementation("CesiumForUnityNative::CesiumSimplePlanarEllipsoidCurveImpl", "CesiumSimplePlanarEllipsoidCurveImpl.h")] [IconAttribute("Packages/com.cesium.unity/Editor/Resources/Cesium-24x24.png")] diff --git a/Runtime/CesiumSubScene.cs b/Runtime/CesiumSubScene.cs index f4a88a3c..ffabb631 100644 --- a/Runtime/CesiumSubScene.cs +++ b/Runtime/CesiumSubScene.cs @@ -387,9 +387,19 @@ private void OnDestroy() private void UpdateOtherCoordinates() { + if(this._parentGeoreference == null) + { + this.UpdateParentReference(); + + if(this._parentGeoreference == null) + { + throw new InvalidOperationException("CesiumSubScene should have been nested inside a game object with a CesiumGeoreference."); + } + } + if (this._originAuthority == CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight) { - double3 ecef = CesiumWgs84Ellipsoid.LongitudeLatitudeHeightToEarthCenteredEarthFixed(new double3( + double3 ecef = this._parentGeoreference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(new double3( this._longitude, this._latitude, this._height @@ -402,7 +412,7 @@ private void UpdateOtherCoordinates() if (this._originAuthority == CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed) { - double3 llh = CesiumWgs84Ellipsoid.EarthCenteredEarthFixedToLongitudeLatitudeHeight(new double3( + double3 llh = this._parentGeoreference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(new double3( this._ecefX, this._ecefY, this._ecefZ diff --git a/Tests/Comparers.cs b/Tests/Comparers.cs index 31e0e54e..3a55a953 100644 --- a/Tests/Comparers.cs +++ b/Tests/Comparers.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Unity.Mathematics; internal class Comparers { @@ -37,6 +38,26 @@ private double RelativeToAbsoluteEpsilon(double left, double right, double relat } } + private class Double3Comparer : IEqualityComparer + { + private DoubleComparer _doubleComparer; + + public Double3Comparer(double absoluteEpsilon, double relativeEpsilon = 0.0) + { + this._doubleComparer = new DoubleComparer(absoluteEpsilon, relativeEpsilon); + } + + public bool Equals(double3 a, double3 b) + { + return _doubleComparer.Equals(a.x, b.x) && _doubleComparer.Equals(a.y, b.y) && _doubleComparer.Equals(a.z, b.z); + } + + public int GetHashCode(double3 obj) + { + throw new NotImplementedException(); + } + } + public static IEqualityComparer Double(double absoluteEpsilon) { return new DoubleComparer(absoluteEpsilon); @@ -46,4 +67,14 @@ public static IEqualityComparer Double(double absoluteEpsilon, double re { return new DoubleComparer(absoluteEpsilon, relativeEpsilon); } + + public static IEqualityComparer Double3(double absoluteEpsilon) + { + return new Double3Comparer(absoluteEpsilon); + } + + public static IEqualityComparer Double3(double absoluteEpsilon, double relativeEpsilon) + { + return new Double3Comparer(absoluteEpsilon, relativeEpsilon); + } } diff --git a/Tests/TestCesiumGlobeAnchor.cs b/Tests/TestCesiumGlobeAnchor.cs index 22c7ade5..69c92ad7 100644 --- a/Tests/TestCesiumGlobeAnchor.cs +++ b/Tests/TestCesiumGlobeAnchor.cs @@ -256,4 +256,38 @@ public IEnumerator SettingTransformPositionAlsoUpdatesOrientation() Assert.That(goAnchored.transform.rotation.eulerAngles.y, Is.Not.EqualTo(20.0f).Using(FloatEqualityComparer.Instance)); Assert.That(goAnchored.transform.rotation.eulerAngles.z, Is.Not.EqualTo(30.0f).Using(FloatEqualityComparer.Instance)); } + + [Test] + public void GivesCorrectResultsForDifferentEllipsoids() + { + IEqualityComparer epsilon6 = Comparers.Double3(1e-6, 1e-4); + + double3 positionLlh = new double3(-20, -10, 1000.0); + + GameObject goGeoreference = new GameObject("Georeference"); + CesiumGeoreference georeference = goGeoreference.AddComponent(); + georeference.ellipsoid = CesiumEllipsoid.WGS84; + georeference.SetOriginLongitudeLatitudeHeight(positionLlh.x, positionLlh.y, positionLlh.z); + + GameObject goAnchored = new GameObject("Anchored"); + goAnchored.transform.parent = goGeoreference.transform; + goAnchored.transform.SetPositionAndRotation(new Vector3(0, 0, 0), Quaternion.identity); + + CesiumGlobeAnchor anchor = goAnchored.AddComponent(); + + // Test WGS84 first + double3 actualPosEcef = CesiumEllipsoid.WGS84.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(positionLlh); + Assert.That(anchor.positionGlobeFixed, Is.EqualTo(actualPosEcef).Using(epsilon6)); + + // Test with unit ellipsoid + CesiumEllipsoid unitEllipsoid = ScriptableObject.CreateInstance(); + unitEllipsoid.SetRadii(new double3(1.0, 1.0, 1.0)); + georeference.ellipsoid = unitEllipsoid; + georeference.SetOriginLongitudeLatitudeHeight(positionLlh.x, positionLlh.y, positionLlh.z); + + actualPosEcef = unitEllipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(positionLlh); + goAnchored.transform.SetPositionAndRotation(new Vector3(0, 0, 0), Quaternion.identity); + anchor.Sync(); + Assert.That(anchor.positionGlobeFixed, Is.EqualTo(actualPosEcef).Using(epsilon6)); + } } From 8faff60340c2935a2b29bdc75b03e5dfb5d72dd2 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 15:04:56 -0400 Subject: [PATCH 09/14] Review changes --- Editor/CesiumGeoreferenceEditor.cs | 1 + Runtime/CesiumEllipsoid.cs | 9 ++-- Runtime/CesiumFlyToController.cs | 6 +-- Runtime/CesiumGeoreference.cs | 14 +++-- Runtime/CesiumGlobeAnchor.cs | 4 +- Runtime/CesiumSimplePlanarEllipsoidCurve.cs | 17 +++++-- Runtime/CesiumSubScene.cs | 4 +- Runtime/ConfigureReinterop.cs | 3 +- Tests/TestCesiumGlobeAnchor.cs | 4 +- Tests/TestCesiumSimplePlanarEllipsoidCurve.cs | 4 +- .../src/CesiumBingMapsRasterOverlayImpl.cpp | 2 +- .../Runtime/src/CesiumEllipsoidFunctions.cpp | 4 +- .../Runtime/src/CesiumEllipsoidFunctions.h | 4 +- native~/Runtime/src/CesiumEllipsoidImpl.cpp | 51 +++++++++++++------ native~/Runtime/src/CesiumEllipsoidImpl.h | 4 +- native~/Runtime/src/CesiumGlobeAnchorImpl.cpp | 6 ++- .../CesiumSimplePlanarEllipsoidCurveImpl.cpp | 2 +- .../CesiumSimplePlanarEllipsoidCurveImpl.h | 2 +- .../Runtime/src/CesiumWgs84EllipsoidImpl.cpp | 4 +- 19 files changed, 90 insertions(+), 55 deletions(-) diff --git a/Editor/CesiumGeoreferenceEditor.cs b/Editor/CesiumGeoreferenceEditor.cs index f2f3ce2f..1b259dc1 100644 --- a/Editor/CesiumGeoreferenceEditor.cs +++ b/Editor/CesiumGeoreferenceEditor.cs @@ -119,6 +119,7 @@ private void DrawEllipsoidOverrideProperty() EditorGUILayout.PropertyField(this._ellipsoidOverride, ellipsoidOverrideContent); if(EditorGUI.EndChangeCheck()) { + this.serializedObject.ApplyModifiedProperties(); this._georeference.ReloadEllipsoid(); } } diff --git a/Runtime/CesiumEllipsoid.cs b/Runtime/CesiumEllipsoid.cs index 247809c3..341a1447 100644 --- a/Runtime/CesiumEllipsoid.cs +++ b/Runtime/CesiumEllipsoid.cs @@ -1,10 +1,6 @@ using Reinterop; using Unity.Mathematics; using UnityEngine; -using Microsoft.Win32.SafeHandles; -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; namespace CesiumForUnity @@ -24,6 +20,7 @@ public static CesiumEllipsoid WGS84 if (_cachedWgs84 == null) { _cachedWgs84 = CreateInstance(); + _cachedWgs84.name = "WGS84"; _cachedWgs84.SetRadii(CesiumWgs84Ellipsoid.GetRadii()); } @@ -95,7 +92,7 @@ public double GetMinimumRadius() /// The longitude (X) and latitude (Y) are in degrees. The height (Z) is in meters above the ellipsoid, /// and should not be confused with a geoid, orthometric, or mean sea level height. /// The ECEF coordinates in meters. - public partial double3 LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(double3 longitudeLatitudeHeight); + public partial double3 LongitudeLatitudeHeightToCenteredFixed(double3 longitudeLatitudeHeight); /// /// Convert Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) coordinates to longitude, latitude, and height. @@ -105,6 +102,6 @@ public double GetMinimumRadius() /// The longitude (X) and latitude (Y) are in degrees. The height (Z) is in meters above the ellipsoid, /// and should not be confused with a geoid, orthometric, or mean sea level height. /// - public partial double3 EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(double3 ellipsoidCenteredEllipsoidFixed); + public partial double3 CenteredFixedToLongitudeLatitudeHeight(double3 ellipsoidCenteredEllipsoidFixed); } } diff --git a/Runtime/CesiumFlyToController.cs b/Runtime/CesiumFlyToController.cs index 0681a44f..51eb7c4d 100644 --- a/Runtime/CesiumFlyToController.cs +++ b/Runtime/CesiumFlyToController.cs @@ -361,7 +361,7 @@ private void ComputeFlightPath( this._destinationRotation = Quaternion.Euler(pitchAtDestination, yawAtDestination, 0.0f); this._destinationECEF = destinationECEF; - this._flightPath = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates( + this._flightPath = CesiumSimplePlanarEllipsoidCurve.FromCenteredFixedCoordinates( this._georeference.ellipsoid, sourceECEF, destinationECEF); @@ -486,7 +486,7 @@ public void FlyToLocationLongitudeLatitudeHeight( bool canInterruptByMoving) { double3 destinationECEF = - this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(destination); + this._georeference.ellipsoid.LongitudeLatitudeHeightToCenteredFixed(destination); this.FlyToLocationEarthCenteredEarthFixed( destinationECEF, @@ -525,7 +525,7 @@ public void FlyToLocationLongitudeLatitudeHeight( z = destination.z }; double3 destinationECEF = - this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + this._georeference.ellipsoid.LongitudeLatitudeHeightToCenteredFixed( destinationCoordinates); this.FlyToLocationEarthCenteredEarthFixed( diff --git a/Runtime/CesiumGeoreference.cs b/Runtime/CesiumGeoreference.cs index 2ae60283..d07d5146 100644 --- a/Runtime/CesiumGeoreference.cs +++ b/Runtime/CesiumGeoreference.cs @@ -265,7 +265,9 @@ public CesiumEllipsoid ellipsoid { if (this._ellipsoid == null) { - this._ellipsoid = this._ellipsoidOverride ?? CesiumEllipsoid.WGS84; + // Make a copy of the ellipsoid ScriptableObject + this._ellipsoid = ScriptableObject.CreateInstance(); + this._ellipsoid.SetRadii((this._ellipsoidOverride ?? CesiumEllipsoid.WGS84).radii); } return this._ellipsoid; @@ -383,7 +385,11 @@ public void Initialize() /// public void ReloadEllipsoid() { - this._ellipsoid = this._ellipsoidOverride ?? CesiumEllipsoid.WGS84; + // clear cached ellipsoid so it has to be rebuilt + this._ellipsoid = null; + this.UpdateTransformations(); + this.UpdateOtherCoordinates(); + Cesium3DTileset[] tilesets = GetComponentsInChildren(); foreach(var tileset in tilesets) { @@ -459,7 +465,7 @@ private void UpdateOtherCoordinates() if (this._originAuthority == CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight) { double3 ecef = - this.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + this.ellipsoid.LongitudeLatitudeHeightToCenteredFixed( new double3(this._longitude, this._latitude, this._height)); this._ecefX = ecef.x; this._ecefY = ecef.y; @@ -468,7 +474,7 @@ private void UpdateOtherCoordinates() else if (this._originAuthority == CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed) { double3 llh = - this.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + this.ellipsoid.CenteredFixedToLongitudeLatitudeHeight( new double3(this._ecefX, this._ecefY, this._ecefZ)); this._longitude = llh.x; this._latitude = llh.y; diff --git a/Runtime/CesiumGlobeAnchor.cs b/Runtime/CesiumGlobeAnchor.cs index 35e9ac66..43637420 100644 --- a/Runtime/CesiumGlobeAnchor.cs +++ b/Runtime/CesiumGlobeAnchor.cs @@ -182,10 +182,10 @@ public double4x4 localToGlobeFixedMatrix /// public double3 longitudeLatitudeHeight { - get => this._georeference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(this.positionGlobeFixed); + get => this._georeference.ellipsoid.CenteredFixedToLongitudeLatitudeHeight(this.positionGlobeFixed); set { - this.positionGlobeFixed = this._georeference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(value); + this.positionGlobeFixed = this._georeference.ellipsoid.LongitudeLatitudeHeightToCenteredFixed(value); } } diff --git a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs index c17cf953..22830bfa 100644 --- a/Runtime/CesiumSimplePlanarEllipsoidCurve.cs +++ b/Runtime/CesiumSimplePlanarEllipsoidCurve.cs @@ -1,4 +1,5 @@ using Reinterop; +using System; using Unity.Mathematics; using UnityEngine; @@ -12,9 +13,17 @@ namespace CesiumForUnity [IconAttribute("Packages/com.cesium.unity/Editor/Resources/Cesium-24x24.png")] public partial class CesiumSimplePlanarEllipsoidCurve { + [Obsolete("Use CesiumSimplePlanarCurve.FromCenteredFixedCoordinates instead.")] + public static CesiumSimplePlanarEllipsoidCurve FromEarthCenteredEarthFixedCoordinates( + CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef) + { + return FromCenteredFixedCoordinates(ellipsoid, sourceEcef, destinationEcef); + } + + /// /// Creates a new object from a pair of - /// Earth-Centered, Earth-Fixed coordinates describing the beginning and end points of the curve. + /// Ellipsoid-Centered, Ellipsoid-Fixed coordinates describing the beginning and end points of the curve. /// /// The start point of the curve. /// The end point of the curve. @@ -22,10 +31,10 @@ public partial class CesiumSimplePlanarEllipsoidCurve /// A if a curve can successfully be /// created between the two points, or null otherwise. /// - public static CesiumSimplePlanarEllipsoidCurve FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef) + public static CesiumSimplePlanarEllipsoidCurve FromCenteredFixedCoordinates(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef) { CesiumSimplePlanarEllipsoidCurve curve = new CesiumSimplePlanarEllipsoidCurve(); - if (!curve.CreateFromEarthCenteredEarthFixedCoordinates(ellipsoid, sourceEcef, destinationEcef)) + if (!curve.CreateFromCenteredFixed(ellipsoid, sourceEcef, destinationEcef)) { return null; } @@ -70,7 +79,7 @@ public static CesiumSimplePlanarEllipsoidCurve FromLongituteLatitudeHeight(Cesiu /// The position of the given point on this curve in Earth-Centered, Earth-Fixed coordinates. public partial double3 GetPosition(double percentage, double additionalHeight = 0.0); - private partial bool CreateFromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef); + private partial bool CreateFromCenteredFixed(CesiumEllipsoid ellipsoid, double3 sourceEcef, double3 destinationEcef); private partial bool CreateFromLongitudeLatitudeHeight(CesiumEllipsoid ellipsoid, double3 sourceLlh, double3 destinationLlh); private CesiumSimplePlanarEllipsoidCurve() diff --git a/Runtime/CesiumSubScene.cs b/Runtime/CesiumSubScene.cs index ffabb631..040be15a 100644 --- a/Runtime/CesiumSubScene.cs +++ b/Runtime/CesiumSubScene.cs @@ -399,7 +399,7 @@ private void UpdateOtherCoordinates() if (this._originAuthority == CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight) { - double3 ecef = this._parentGeoreference.ellipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(new double3( + double3 ecef = this._parentGeoreference.ellipsoid.LongitudeLatitudeHeightToCenteredFixed(new double3( this._longitude, this._latitude, this._height @@ -412,7 +412,7 @@ private void UpdateOtherCoordinates() if (this._originAuthority == CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed) { - double3 llh = this._parentGeoreference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(new double3( + double3 llh = this._parentGeoreference.ellipsoid.CenteredFixedToLongitudeLatitudeHeight(new double3( this._ecefX, this._ecefY, this._ecefZ diff --git a/Runtime/ConfigureReinterop.cs b/Runtime/ConfigureReinterop.cs index 59d284ab..0109a3fc 100644 --- a/Runtime/ConfigureReinterop.cs +++ b/Runtime/ConfigureReinterop.cs @@ -148,6 +148,7 @@ public void ExposeToCPP() Debug.Log("Logging"); Debug.LogWarning("Warning"); + Debug.LogError("Error"); MeshRenderer meshRenderer = new MeshRenderer(); GameObject meshGameObject = meshRenderer.gameObject; @@ -517,7 +518,7 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails CesiumGlobeAnchor globeAnchor = globeAnchors[globeAnchors.Length - 1]; globeAnchor.positionGlobeFixed = globeAnchor.positionGlobeFixed; - CesiumSimplePlanarEllipsoidCurve planarEllipsoidCurve = CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates( + CesiumSimplePlanarEllipsoidCurve planarEllipsoidCurve = CesiumSimplePlanarEllipsoidCurve.FromCenteredFixedCoordinates( CesiumEllipsoid.WGS84, new double3(0, 0, 0), new double3(0, 0, 0)); diff --git a/Tests/TestCesiumGlobeAnchor.cs b/Tests/TestCesiumGlobeAnchor.cs index 69c92ad7..ddd1c87e 100644 --- a/Tests/TestCesiumGlobeAnchor.cs +++ b/Tests/TestCesiumGlobeAnchor.cs @@ -276,7 +276,7 @@ public void GivesCorrectResultsForDifferentEllipsoids() CesiumGlobeAnchor anchor = goAnchored.AddComponent(); // Test WGS84 first - double3 actualPosEcef = CesiumEllipsoid.WGS84.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(positionLlh); + double3 actualPosEcef = CesiumEllipsoid.WGS84.LongitudeLatitudeHeightToCenteredFixed(positionLlh); Assert.That(anchor.positionGlobeFixed, Is.EqualTo(actualPosEcef).Using(epsilon6)); // Test with unit ellipsoid @@ -285,7 +285,7 @@ public void GivesCorrectResultsForDifferentEllipsoids() georeference.ellipsoid = unitEllipsoid; georeference.SetOriginLongitudeLatitudeHeight(positionLlh.x, positionLlh.y, positionLlh.z); - actualPosEcef = unitEllipsoid.LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(positionLlh); + actualPosEcef = unitEllipsoid.CenteredFixedToLongitudeLatitudeHeight(positionLlh); goAnchored.transform.SetPositionAndRotation(new Vector3(0, 0, 0), Quaternion.identity); anchor.Sync(); Assert.That(anchor.positionGlobeFixed, Is.EqualTo(actualPosEcef).Using(epsilon6)); diff --git a/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs b/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs index 6ff3cd06..f753b3c6 100644 --- a/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs +++ b/Tests/TestCesiumSimplePlanarEllipsoidCurve.cs @@ -21,7 +21,7 @@ private double3 RelativeToAbsoluteEpsilon(double3 left, double3 right, double re public IEnumerator StartAndEndOfPathAreIdenticalToInput() { CesiumSimplePlanarEllipsoidCurve flightPath = - CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); + CesiumSimplePlanarEllipsoidCurve.FromCenteredFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); Assert.IsNotNull(flightPath); double3 startPosition = flightPath.GetPosition(0.0); @@ -43,7 +43,7 @@ public IEnumerator StartAndEndOfPathAreIdenticalToInput() public IEnumerator ShouldCalculateMidpointCorrectly() { CesiumSimplePlanarEllipsoidCurve flightPath = - CesiumSimplePlanarEllipsoidCurve.FromEarthCenteredEarthFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); + CesiumSimplePlanarEllipsoidCurve.FromCenteredFixedCoordinates(CesiumEllipsoid.WGS84, _philadelphiaEcef, _tokyoEcef); Assert.IsNotNull(flightPath); double3 expectedResult = new double3( diff --git a/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp b/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp index 0a0e1f27..e56ba926 100644 --- a/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp +++ b/native~/Runtime/src/CesiumBingMapsRasterOverlayImpl.cpp @@ -81,7 +81,7 @@ void CesiumBingMapsRasterOverlayImpl::AddToTileset( overlay.bingMapsKey().ToStlString(), mapStyle, "", - tileset.NativeImplementation().getTileset()->getEllipsoid(), + pTileset->getEllipsoid(), options); pTileset->getOverlays().add(this->_pOverlay); diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.cpp b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp index ab1857d4..bead28d4 100644 --- a/native~/Runtime/src/CesiumEllipsoidFunctions.cpp +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp @@ -39,7 +39,7 @@ CesiumEllipsoidFunctions::GeodeticSurfaceNormal( } DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + LongitudeLatitudeHeightToCenteredFixed( const CesiumGeospatial::Ellipsoid& ellipsoid, DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight) { glm::dvec3 cartesian = @@ -51,7 +51,7 @@ DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: } DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + CenteredFixedToLongitudeLatitudeHeight( const CesiumGeospatial::Ellipsoid& ellipsoid, DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed) { std::optional result = diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.h b/native~/Runtime/src/CesiumEllipsoidFunctions.h index 57631e93..9cb19daf 100644 --- a/native~/Runtime/src/CesiumEllipsoidFunctions.h +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.h @@ -18,11 +18,11 @@ class CesiumEllipsoidFunctions { const CesiumGeospatial::Ellipsoid& ellipsoid, DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed); static DotNet::Unity::Mathematics::double3 - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + LongitudeLatitudeHeightToCenteredFixed( const CesiumGeospatial::Ellipsoid& ellipsoid, DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight); static DotNet::Unity::Mathematics::double3 - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + CenteredFixedToLongitudeLatitudeHeight( const CesiumGeospatial::Ellipsoid& ellipsoid, DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed); }; diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.cpp b/native~/Runtime/src/CesiumEllipsoidImpl.cpp index af5994ee..be04d46a 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumEllipsoidImpl.cpp @@ -3,17 +3,23 @@ #include "CesiumEllipsoidFunctions.h" #include +#include #include +#include +#include + +#include using namespace DotNet::Unity::Mathematics; using namespace DotNet::CesiumForUnity; +static constexpr double MinRadiiValue = std::numeric_limits::epsilon(); + CesiumForUnityNative::CesiumEllipsoidImpl::CesiumEllipsoidImpl( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid) - : _ellipsoid( - unityEllipsoid.radii().x, - unityEllipsoid.radii().y, - unityEllipsoid.radii().z) {} + : _ellipsoid(1.0, 1.0, 1.0) { + this->SetRadii(unityEllipsoid, unityEllipsoid.radii()); +} CesiumForUnityNative::CesiumEllipsoidImpl::~CesiumEllipsoidImpl() {} @@ -26,8 +32,23 @@ CesiumForUnityNative::CesiumEllipsoidImpl::GetRadii( void CesiumForUnityNative::CesiumEllipsoidImpl::SetRadii( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& newRadii) { - this->_ellipsoid = - CesiumGeospatial::Ellipsoid(newRadii.x, newRadii.y, newRadii.z); + if (newRadii.x < MinRadiiValue || newRadii.y < MinRadiiValue || + newRadii.z < MinRadiiValue) { + DotNet::UnityEngine::Debug::LogError( + DotNet::System::String("Ellipsoid radii must be greater than 0 - " + "clamping to minimum value to avoid crashes.")); + } + + double3 clampedRadii = double3::Construct( + std::max(newRadii.x, MinRadiiValue), + std::max(newRadii.y, MinRadiiValue), + std::max(newRadii.z, MinRadiiValue)); + + this->_ellipsoid = CesiumGeospatial::Ellipsoid( + clampedRadii.x, + clampedRadii.y, + clampedRadii.z); + unityEllipsoid.radii(clampedRadii); } std::optional @@ -51,22 +72,20 @@ CesiumForUnityNative::CesiumEllipsoidImpl::GeodeticSurfaceNormal( } DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + LongitudeLatitudeHeightToCenteredFixed( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& longitudeLatitudeHeight) { - return CesiumEllipsoidFunctions:: - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( - this->_ellipsoid, - longitudeLatitudeHeight); + return CesiumEllipsoidFunctions::LongitudeLatitudeHeightToCenteredFixed( + this->_ellipsoid, + longitudeLatitudeHeight); } DotNet::Unity::Mathematics::double3 CesiumForUnityNative::CesiumEllipsoidImpl:: - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + CenteredFixedToLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed) { - return CesiumEllipsoidFunctions:: - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( - this->_ellipsoid, - ellipsoidCenteredEllipsoidFixed); + return CesiumEllipsoidFunctions::CenteredFixedToLongitudeLatitudeHeight( + this->_ellipsoid, + ellipsoidCenteredEllipsoidFixed); } diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.h b/native~/Runtime/src/CesiumEllipsoidImpl.h index bd0fb053..78f76edc 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.h +++ b/native~/Runtime/src/CesiumEllipsoidImpl.h @@ -36,12 +36,12 @@ class CesiumEllipsoidImpl { ellipsoidCenteredEllipsoidFixed); DotNet::Unity::Mathematics::double3 - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + LongitudeLatitudeHeightToCenteredFixed( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& longitudeLatitudeHeight); DotNet::Unity::Mathematics::double3 - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + CenteredFixedToLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); diff --git a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp index 7efd88e0..101a0995 100644 --- a/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp +++ b/native~/Runtime/src/CesiumGlobeAnchorImpl.cpp @@ -192,8 +192,10 @@ void CesiumGlobeAnchorImpl::SetLocalToEastUpNorthRotation( GlobeAnchor cppAnchor( UnityTransforms::fromUnity(anchor._localToGlobeFixedMatrix())); + const CesiumGeospatial::Ellipsoid& ellipsoid = getAnchorEllipsoid(anchor); + LocalHorizontalCoordinateSystem eastUpNorth = - createEastUpNorth(cppAnchor, getAnchorEllipsoid(anchor)); + createEastUpNorth(cppAnchor, ellipsoid); glm::dmat4 modelToEastUpNorth = cppAnchor.getAnchorToLocalTransform(eastUpNorth); @@ -216,7 +218,7 @@ void CesiumGlobeAnchorImpl::SetLocalToEastUpNorthRotation( eastUpNorth, newModelToEastUpNorth, false, - getAnchorEllipsoid(anchor)); + ellipsoid); updateAnchorFromCpp(anchor, cppAnchor); } diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp index f129aea7..6224f2ed 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp @@ -15,7 +15,7 @@ CesiumSimplePlanarEllipsoidCurveImpl::CesiumSimplePlanarEllipsoidCurveImpl( CesiumSimplePlanarEllipsoidCurveImpl::~CesiumSimplePlanarEllipsoidCurveImpl() {} bool CesiumSimplePlanarEllipsoidCurveImpl:: - CreateFromEarthCenteredEarthFixedCoordinates( + CreateFromCenteredFixed( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceEcef, diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h index 4d891f6e..a6c543d2 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.h @@ -23,7 +23,7 @@ class CesiumSimplePlanarEllipsoidCurveImpl { const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path); ~CesiumSimplePlanarEllipsoidCurveImpl(); - bool CreateFromEarthCenteredEarthFixedCoordinates( + bool CreateFromCenteredFixed( const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, const DotNet::Unity::Mathematics::double3 sourceEcef, diff --git a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp index 1f1ace1c..9f65e44f 100644 --- a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp @@ -34,7 +34,7 @@ double3 CesiumWgs84EllipsoidImpl::LongitudeLatitudeHeightToEarthCenteredEarthFixed( double3 longitudeLatitudeHeight) { return CesiumEllipsoidFunctions:: - LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed( + LongitudeLatitudeHeightToCenteredFixed( Ellipsoid::WGS84, longitudeLatitudeHeight); } @@ -43,7 +43,7 @@ double3 CesiumWgs84EllipsoidImpl::EarthCenteredEarthFixedToLongitudeLatitudeHeight( double3 earthCenteredEarthFixed) { return CesiumEllipsoidFunctions:: - EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight( + CenteredFixedToLongitudeLatitudeHeight( Ellipsoid::WGS84, earthCenteredEarthFixed); } From f2b21236583ab3a5f42d329de4008b7fe216b30f Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 15:05:43 -0400 Subject: [PATCH 10/14] Update to latest cesium-native --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 110ff3b0..dbc8e118 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 110ff3b00919db6fbe7865af6d35c96c9311653e +Subproject commit dbc8e118581e3ee2eee00fc8fec001fa60e3b8b6 From ae6bd4d6ce51c2c3c5739d6caf883c5e8fd5e582 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 15:56:04 -0400 Subject: [PATCH 11/14] Fix WGS84 default parameters --- Runtime/Cesium3DTile.cs | 5 +++-- Runtime/CesiumCartographicPolygon.cs | 2 +- Runtime/CesiumGlobeAnchor.cs | 18 +++++++++++++++--- Runtime/ConfigureReinterop.cs | 1 + native~/Runtime/src/Cesium3DTileImpl.cpp | 8 +++++++- native~/Runtime/src/Cesium3DTileImpl.h | 1 + native~/Runtime/src/Cesium3DTilesetImpl.cpp | 2 +- .../Runtime/src/UnityTileExcluderAdaptor.cpp | 8 ++++++++ 8 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Runtime/Cesium3DTile.cs b/Runtime/Cesium3DTile.cs index 016e280e..1aff7962 100644 --- a/Runtime/Cesium3DTile.cs +++ b/Runtime/Cesium3DTile.cs @@ -15,6 +15,7 @@ public partial class Cesium3DTile { internal double4x4 _transform; internal IntPtr _pTile; + internal IntPtr _pTileEllipsoid; internal Cesium3DTile() {} @@ -27,10 +28,10 @@ public Bounds bounds { get { - return Cesium3DTile.getBounds(this._pTile, this._transform); + return Cesium3DTile.getBounds(this._pTile, this._pTileEllipsoid, this._transform); } } - private static partial Bounds getBounds(IntPtr pTile, double4x4 ecefToLocalMatrix); + private static partial Bounds getBounds(IntPtr pTile, IntPtr pTileEllipsoid, double4x4 ecefToLocalMatrix); } } diff --git a/Runtime/CesiumCartographicPolygon.cs b/Runtime/CesiumCartographicPolygon.cs index 1ab917f1..270f94e2 100644 --- a/Runtime/CesiumCartographicPolygon.cs +++ b/Runtime/CesiumCartographicPolygon.cs @@ -138,7 +138,7 @@ internal List GetCartographicPoints(Matrix4x4 worldToTileset) float3 worldPosition = knot.Transform(localToWorld).Position; float3 unityPosition = worldToTileset.MultiplyPoint3x4(worldPosition); double3 ecefPosition = georeference.TransformUnityPositionToEarthCenteredEarthFixed(unityPosition); - double3 cartographicPosition = georeference.ellipsoid.EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(ecefPosition); + double3 cartographicPosition = georeference.ellipsoid.LongitudeLatitudeHeightToCenteredFixed(ecefPosition); cartographicPoints.Add(cartographicPosition.xy); } diff --git a/Runtime/CesiumGlobeAnchor.cs b/Runtime/CesiumGlobeAnchor.cs index 43637420..840314ea 100644 --- a/Runtime/CesiumGlobeAnchor.cs +++ b/Runtime/CesiumGlobeAnchor.cs @@ -84,6 +84,9 @@ public partial class CesiumGlobeAnchor : MonoBehaviour, ICesiumRestartable [NonSerialized] internal CesiumGeoreference _georeference; + [NonSerialized] + internal double3? _lastEllipsoidRadii; + #endregion #region User-editable properties @@ -396,7 +399,7 @@ public void SetPositionLongitudeLatitudeHeight(double longitude, double latitude this.longitudeLatitudeHeight = new double3(longitude, latitude, height); } - + [Obsolete("Set the positionGlobeFixed property instead.")] public void SetPositionEarthCenteredEarthFixed(double x, double y, double z) { @@ -444,9 +447,16 @@ public void SetPositionEarthCenteredEarthFixed(double x, double y, double z) /// public void Sync() { + // If the ellipsoid changed since last sync, we need to update from transform since our ECEF mapping + // is going to be invalid. + bool isEllipsoidChanged = _lastEllipsoidRadii.HasValue ? + (_lastEllipsoidRadii.Value.x != _georeference.ellipsoid.radii.x || + _lastEllipsoidRadii.Value.y != _georeference.ellipsoid.radii.y || + _lastEllipsoidRadii.Value.z != _georeference.ellipsoid.radii.z) : true; + // If we don't have a local -> globe fixed matrix yet, we must update from the Transform bool updateFromTransform = !this._localToGlobeFixedMatrixIsValid; - if (!updateFromTransform && this._lastLocalsAreValid) + if (!isEllipsoidChanged && !updateFromTransform && this._lastLocalsAreValid) { // We may also need to update from the Transform if it has changed // since the last time we computed the local -> globe fixed matrix. @@ -456,7 +466,9 @@ public void Sync() this._lastLocalScale != this.transform.localScale; } - if (updateFromTransform) + _lastEllipsoidRadii = _georeference.ellipsoid.radii; + + if (isEllipsoidChanged || updateFromTransform) this.UpdateEcefFromTransform(); else this.UpdateEcef(this._localToGlobeFixedMatrix); diff --git a/Runtime/ConfigureReinterop.cs b/Runtime/ConfigureReinterop.cs index 0109a3fc..1722bd91 100644 --- a/Runtime/ConfigureReinterop.cs +++ b/Runtime/ConfigureReinterop.cs @@ -550,6 +550,7 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails Cesium3DTile tile = new Cesium3DTile(); tile._transform = new double4x4(); tile._pTile = IntPtr.Zero; + tile._pTileEllipsoid = IntPtr.Zero; Cesium3DTileInfo info; info.usesAdditiveRefinement = true; diff --git a/native~/Runtime/src/Cesium3DTileImpl.cpp b/native~/Runtime/src/Cesium3DTileImpl.cpp index 247d337e..5cb82cd3 100644 --- a/native~/Runtime/src/Cesium3DTileImpl.cpp +++ b/native~/Runtime/src/Cesium3DTileImpl.cpp @@ -3,21 +3,27 @@ #include "UnityTransforms.h" #include +#include #include #include using namespace Cesium3DTilesSelection; using namespace CesiumGeometry; +using namespace CesiumGeospatial; namespace CesiumForUnityNative { DotNet::UnityEngine::Bounds Cesium3DTileImpl::getBounds( void* pTileVoid, + void* pTileEllipsoidVoid, const DotNet::Unity::Mathematics::double4x4& ecefToLocalMatrix) { const Tile* pTile = static_cast(pTileVoid); + const Ellipsoid* pTileEllipsoid = + static_cast(pTileEllipsoidVoid); const BoundingVolume& bv = pTile->getBoundingVolume(); - OrientedBoundingBox obb = getOrientedBoundingBoxFromBoundingVolume(bv); + OrientedBoundingBox obb = + getOrientedBoundingBoxFromBoundingVolume(bv, *pTileEllipsoid); obb = obb.transform(UnityTransforms::fromUnity(ecefToLocalMatrix)); AxisAlignedBox aabb = obb.toAxisAligned(); return DotNet::UnityEngine::Bounds::Construct( diff --git a/native~/Runtime/src/Cesium3DTileImpl.h b/native~/Runtime/src/Cesium3DTileImpl.h index 4a65326e..4d0818e3 100644 --- a/native~/Runtime/src/Cesium3DTileImpl.h +++ b/native~/Runtime/src/Cesium3DTileImpl.h @@ -14,6 +14,7 @@ class Cesium3DTileImpl { public: static DotNet::UnityEngine::Bounds getBounds( void* pTileVoid, + void* pTileEllipsoidVoid, const DotNet::Unity::Mathematics::double4x4& ecefToLocalMatrix); }; diff --git a/native~/Runtime/src/Cesium3DTilesetImpl.cpp b/native~/Runtime/src/Cesium3DTilesetImpl.cpp index bddd80ea..d6188183 100644 --- a/native~/Runtime/src/Cesium3DTilesetImpl.cpp +++ b/native~/Runtime/src/Cesium3DTilesetImpl.cpp @@ -267,7 +267,7 @@ struct CalculateECEFCameraPosition { } glm::dvec3 operator()(const CesiumGeospatial::S2CellBoundingVolume& s2) { - return (*this)(s2.computeBoundingRegion()); + return (*this)(s2.computeBoundingRegion(ellipsoid)); } }; } // namespace diff --git a/native~/Runtime/src/UnityTileExcluderAdaptor.cpp b/native~/Runtime/src/UnityTileExcluderAdaptor.cpp index 8d544bc9..80566e57 100644 --- a/native~/Runtime/src/UnityTileExcluderAdaptor.cpp +++ b/native~/Runtime/src/UnityTileExcluderAdaptor.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -64,7 +66,13 @@ bool UnityTileExcluderAdaptor::shouldExclude( return false; } + const CesiumGeospatial::Ellipsoid ellipsoid = + _georeference.ellipsoid().NativeImplementation().GetEllipsoid(); + this->_tile._pTile(const_cast(&tile)); + // it's ok for us to pass by pointer since it will only be valid for this call anyways + this->_tile + ._pTileEllipsoid(const_cast(&ellipsoid)); return this->_excluder.ShouldExclude(this->_tile); } From 9c17b0dec99016bd6f7074accf18023f734d0280 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 16:25:24 -0400 Subject: [PATCH 12/14] Fix test, revert tileset externals --- Tests/TestCesiumGlobeAnchor.cs | 6 +++--- native~/Runtime/src/Cesium3DTilesetImpl.cpp | 4 ++-- native~/Runtime/src/UnityTilesetExternals.cpp | 9 +++------ native~/Runtime/src/UnityTilesetExternals.h | 6 ++---- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Tests/TestCesiumGlobeAnchor.cs b/Tests/TestCesiumGlobeAnchor.cs index ddd1c87e..c5eb75cf 100644 --- a/Tests/TestCesiumGlobeAnchor.cs +++ b/Tests/TestCesiumGlobeAnchor.cs @@ -237,7 +237,7 @@ public IEnumerator SettingTransformPositionAlsoUpdatesOrientation() // Modify the object's position via the Transform. goAnchored.transform.position = new Vector3(20000.0f, 3000.0f, -80000.0f); - + // The orientation should not immediately change, because the coroutine has to run first. Assert.That(goAnchored.transform.position.x, Is.EqualTo(20000.0f).Using(FloatEqualityComparer.Instance)); Assert.That(goAnchored.transform.position.y, Is.EqualTo(3000.0f).Using(FloatEqualityComparer.Instance)); @@ -263,7 +263,7 @@ public void GivesCorrectResultsForDifferentEllipsoids() IEqualityComparer epsilon6 = Comparers.Double3(1e-6, 1e-4); double3 positionLlh = new double3(-20, -10, 1000.0); - + GameObject goGeoreference = new GameObject("Georeference"); CesiumGeoreference georeference = goGeoreference.AddComponent(); georeference.ellipsoid = CesiumEllipsoid.WGS84; @@ -285,7 +285,7 @@ public void GivesCorrectResultsForDifferentEllipsoids() georeference.ellipsoid = unitEllipsoid; georeference.SetOriginLongitudeLatitudeHeight(positionLlh.x, positionLlh.y, positionLlh.z); - actualPosEcef = unitEllipsoid.CenteredFixedToLongitudeLatitudeHeight(positionLlh); + actualPosEcef = unitEllipsoid.LongitudeLatitudeHeightToCenteredFixed(positionLlh); goAnchored.transform.SetPositionAndRotation(new Vector3(0, 0, 0), Quaternion.identity); anchor.Sync(); Assert.That(anchor.positionGlobeFixed, Is.EqualTo(actualPosEcef).Using(epsilon6)); diff --git a/native~/Runtime/src/Cesium3DTilesetImpl.cpp b/native~/Runtime/src/Cesium3DTilesetImpl.cpp index d6188183..186b3a07 100644 --- a/native~/Runtime/src/Cesium3DTilesetImpl.cpp +++ b/native~/Runtime/src/Cesium3DTilesetImpl.cpp @@ -563,7 +563,7 @@ void Cesium3DTilesetImpl::LoadTileset( ionAssetEndpointUrl += '/'; this->_pTileset = std::make_unique( - createTilesetExternals(tileset, options.ellipsoid), + createTilesetExternals(tileset), tileset.ionAssetID(), ionAccessToken.ToStlString(), options, @@ -574,7 +574,7 @@ void Cesium3DTilesetImpl::LoadTileset( } } else { this->_pTileset = std::make_unique( - createTilesetExternals(tileset, options.ellipsoid), + createTilesetExternals(tileset), tileset.url().ToStlString(), options); } diff --git a/native~/Runtime/src/UnityTilesetExternals.cpp b/native~/Runtime/src/UnityTilesetExternals.cpp index 9ad9cfb1..45001fb8 100644 --- a/native~/Runtime/src/UnityTilesetExternals.cpp +++ b/native~/Runtime/src/UnityTilesetExternals.cpp @@ -4,7 +4,6 @@ #include "UnityPrepareRendererResources.h" #include "UnityTaskProcessor.h" -#include #include #include #include @@ -91,16 +90,14 @@ getOrCreateCreditSystem(const CesiumForUnity::Cesium3DTileset& tileset) { return pCreditSystem; } -Cesium3DTilesSelection::TilesetExternals createTilesetExternals( - const CesiumForUnity::Cesium3DTileset& tileset, - const CesiumGeospatial::Ellipsoid& ellipsoid) { - TilesetExternals externals = TilesetExternals{ +Cesium3DTilesSelection::TilesetExternals +createTilesetExternals(const CesiumForUnity::Cesium3DTileset& tileset) { + return TilesetExternals{ getAssetAccessor(), std::make_shared(tileset.gameObject()), AsyncSystem(getTaskProcessor()), getOrCreateCreditSystem(tileset), spdlog::default_logger()}; - return externals; } } // namespace CesiumForUnityNative diff --git a/native~/Runtime/src/UnityTilesetExternals.h b/native~/Runtime/src/UnityTilesetExternals.h index bf3dfaf9..01bd5bd4 100644 --- a/native~/Runtime/src/UnityTilesetExternals.h +++ b/native~/Runtime/src/UnityTilesetExternals.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include @@ -36,8 +35,7 @@ CesiumAsync::AsyncSystem getAsyncSystem(); const std::shared_ptr& getOrCreateCreditSystem(const DotNet::CesiumForUnity::Cesium3DTileset& tileset); -Cesium3DTilesSelection::TilesetExternals createTilesetExternals( - const DotNet::CesiumForUnity::Cesium3DTileset& tileset, - const CesiumGeospatial::Ellipsoid& ellipsoid); +Cesium3DTilesSelection::TilesetExternals +createTilesetExternals(const DotNet::CesiumForUnity::Cesium3DTileset& tileset); } // namespace CesiumForUnityNative From c1fa069e205918dd02d7a1aac678d0e06608b98c Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 16:30:03 -0400 Subject: [PATCH 13/14] Format --- native~/Runtime/src/CesiumEllipsoidFunctions.cpp | 16 ++++++++-------- native~/Runtime/src/CesiumEllipsoidImpl.cpp | 2 +- native~/Runtime/src/CesiumEllipsoidImpl.h | 6 ++---- .../src/CesiumSimplePlanarEllipsoidCurveImpl.cpp | 11 +++++------ native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp | 14 ++++++-------- native~/Runtime/src/UnityTileExcluderAdaptor.cpp | 7 ++++--- 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/native~/Runtime/src/CesiumEllipsoidFunctions.cpp b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp index bead28d4..c419435e 100644 --- a/native~/Runtime/src/CesiumEllipsoidFunctions.cpp +++ b/native~/Runtime/src/CesiumEllipsoidFunctions.cpp @@ -38,10 +38,10 @@ CesiumEllipsoidFunctions::GeodeticSurfaceNormal( return double3{result.x, result.y, result.z}; } -DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: - LongitudeLatitudeHeightToCenteredFixed( - const CesiumGeospatial::Ellipsoid& ellipsoid, - DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight) { +DotNet::Unity::Mathematics::double3 +CesiumEllipsoidFunctions::LongitudeLatitudeHeightToCenteredFixed( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 longitudeLatitudeHeight) { glm::dvec3 cartesian = ellipsoid.cartographicToCartesian(Cartographic::fromDegrees( longitudeLatitudeHeight.x, @@ -50,10 +50,10 @@ DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: return double3{cartesian.x, cartesian.y, cartesian.z}; } -DotNet::Unity::Mathematics::double3 CesiumEllipsoidFunctions:: - CenteredFixedToLongitudeLatitudeHeight( - const CesiumGeospatial::Ellipsoid& ellipsoid, - DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed) { +DotNet::Unity::Mathematics::double3 +CesiumEllipsoidFunctions::CenteredFixedToLongitudeLatitudeHeight( + const CesiumGeospatial::Ellipsoid& ellipsoid, + DotNet::Unity::Mathematics::double3 earthCenteredEarthFixed) { std::optional result = ellipsoid.cartesianToCartographic(glm::dvec3( earthCenteredEarthFixed.x, diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.cpp b/native~/Runtime/src/CesiumEllipsoidImpl.cpp index be04d46a..e19a78f1 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumEllipsoidImpl.cpp @@ -3,10 +3,10 @@ #include "CesiumEllipsoidFunctions.h" #include +#include #include #include #include -#include #include diff --git a/native~/Runtime/src/CesiumEllipsoidImpl.h b/native~/Runtime/src/CesiumEllipsoidImpl.h index 78f76edc..6240b184 100644 --- a/native~/Runtime/src/CesiumEllipsoidImpl.h +++ b/native~/Runtime/src/CesiumEllipsoidImpl.h @@ -35,13 +35,11 @@ class CesiumEllipsoidImpl { const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); - DotNet::Unity::Mathematics::double3 - LongitudeLatitudeHeightToCenteredFixed( + DotNet::Unity::Mathematics::double3 LongitudeLatitudeHeightToCenteredFixed( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& longitudeLatitudeHeight); - DotNet::Unity::Mathematics::double3 - CenteredFixedToLongitudeLatitudeHeight( + DotNet::Unity::Mathematics::double3 CenteredFixedToLongitudeLatitudeHeight( const DotNet::CesiumForUnity::CesiumEllipsoid& unityEllipsoid, const DotNet::Unity::Mathematics::double3& ellipsoidCenteredEllipsoidFixed); diff --git a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp index 6224f2ed..116668df 100644 --- a/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp +++ b/native~/Runtime/src/CesiumSimplePlanarEllipsoidCurveImpl.cpp @@ -14,12 +14,11 @@ CesiumSimplePlanarEllipsoidCurveImpl::CesiumSimplePlanarEllipsoidCurveImpl( CesiumSimplePlanarEllipsoidCurveImpl::~CesiumSimplePlanarEllipsoidCurveImpl() {} -bool CesiumSimplePlanarEllipsoidCurveImpl:: - CreateFromCenteredFixed( - const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, - const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, - const DotNet::Unity::Mathematics::double3 sourceEcef, - const DotNet::Unity::Mathematics::double3 destinationEcef) { +bool CesiumSimplePlanarEllipsoidCurveImpl::CreateFromCenteredFixed( + const DotNet::CesiumForUnity::CesiumSimplePlanarEllipsoidCurve& path, + const DotNet::CesiumForUnity::CesiumEllipsoid& ellipsoid, + const DotNet::Unity::Mathematics::double3 sourceEcef, + const DotNet::Unity::Mathematics::double3 destinationEcef) { this->_curve = SimplePlanarEllipsoidCurve::fromEarthCenteredEarthFixedCoordinates( ellipsoid.NativeImplementation().GetEllipsoid(), diff --git a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp index 9f65e44f..52781b3d 100644 --- a/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp +++ b/native~/Runtime/src/CesiumWgs84EllipsoidImpl.cpp @@ -33,19 +33,17 @@ double3 CesiumWgs84EllipsoidImpl::GeodeticSurfaceNormal( double3 CesiumWgs84EllipsoidImpl::LongitudeLatitudeHeightToEarthCenteredEarthFixed( double3 longitudeLatitudeHeight) { - return CesiumEllipsoidFunctions:: - LongitudeLatitudeHeightToCenteredFixed( - Ellipsoid::WGS84, - longitudeLatitudeHeight); + return CesiumEllipsoidFunctions::LongitudeLatitudeHeightToCenteredFixed( + Ellipsoid::WGS84, + longitudeLatitudeHeight); } double3 CesiumWgs84EllipsoidImpl::EarthCenteredEarthFixedToLongitudeLatitudeHeight( double3 earthCenteredEarthFixed) { - return CesiumEllipsoidFunctions:: - CenteredFixedToLongitudeLatitudeHeight( - Ellipsoid::WGS84, - earthCenteredEarthFixed); + return CesiumEllipsoidFunctions::CenteredFixedToLongitudeLatitudeHeight( + Ellipsoid::WGS84, + earthCenteredEarthFixed); } } // namespace CesiumForUnityNative diff --git a/native~/Runtime/src/UnityTileExcluderAdaptor.cpp b/native~/Runtime/src/UnityTileExcluderAdaptor.cpp index 80566e57..2e361d4b 100644 --- a/native~/Runtime/src/UnityTileExcluderAdaptor.cpp +++ b/native~/Runtime/src/UnityTileExcluderAdaptor.cpp @@ -70,9 +70,10 @@ bool UnityTileExcluderAdaptor::shouldExclude( _georeference.ellipsoid().NativeImplementation().GetEllipsoid(); this->_tile._pTile(const_cast(&tile)); - // it's ok for us to pass by pointer since it will only be valid for this call anyways - this->_tile - ._pTileEllipsoid(const_cast(&ellipsoid)); + // it's ok for us to pass by pointer since it will only be valid for this call + // anyways + this->_tile._pTileEllipsoid( + const_cast(&ellipsoid)); return this->_excluder.ShouldExclude(this->_tile); } From 0aee45657c5d46f2a69202293bfec810a1f425cd Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 27 Jun 2024 16:40:45 -0400 Subject: [PATCH 14/14] Update CHANGES.md --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 16312bbd..8432d01d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,11 @@ - Fixed a bug that caused Cesium ion tokens selected on the Tokens panel to fail to save. - Fixed a bug that caused the "Select Cesium ion Token" panel to show the wrong state when the current token was not from the currently-signed-in Cesium ion account, but the signed-in account had a token named after the current Unity project. +##### Additions :tada: +- Added support for custom non-WGS84 ellipsoids. + - The ellipsoid can be changed by specifying a `CesiumEllipsoid` asset in the new "Ellipsoid Override" property of a `CesiumGeoreference`. + - New `CesiumEllipsoid` assets can be created using the menu option `Assets > Create > Cesium > Ellipsoid`. + ### v1.10.1 - 2024-06-03 This release updates [cesium-native](https://github.com/CesiumGS/cesium-native) from v0.35.0 to v0.36.0. See the [changelog](https://github.com/CesiumGS/cesium-native/blob/main/CHANGES.md) for a complete list of changes in cesium-native.