Cesium for Unity 1.23.0
Loading...
Searching...
No Matches
CesiumGeoreference.cs
Go to the documentation of this file.
1using Reinterop;
2using System;
3using System.Collections.Generic;
4using Unity.Mathematics;
5using UnityEngine;
6
7namespace CesiumForUnity
8{
32
53
85 [ExecuteInEditMode]
86 [ReinteropNativeImplementation("CesiumForUnityNative::CesiumGeoreferenceImpl", "CesiumGeoreferenceImpl.h")]
87 [AddComponentMenu("Cesium/Cesium Georeference")]
88 [IconAttribute("Packages/com.cesium.unity/Editor/Resources/Cesium-24x24.png")]
89 public partial class CesiumGeoreference : MonoBehaviour
90 {
91 #region Fields
92 [SerializeField]
93 private CesiumEllipsoid _ellipsoidOverride = null;
94
95 [SerializeField]
96 private CesiumGeoreferenceOriginPlacement _originPlacement = CesiumGeoreferenceOriginPlacement.CartographicOrigin;
97
98 [SerializeField]
99 private CesiumGeoreferenceOriginAuthority _originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;
100
101 [SerializeField]
102 private double _latitude = 39.736401;
103
104 [SerializeField]
105 private double _longitude = -105.25737;
106
107 [SerializeField]
108 [Delayed]
109 private double _height = 2250.0;
110
111 [SerializeField]
112 [Delayed]
113 private double _ecefX = 6378137.0;
114
115 [SerializeField]
116 [Delayed]
117 private double _ecefY = 0.0;
118
119 [SerializeField]
120 [Delayed]
121 private double _ecefZ = 0.0;
122
123 [SerializeField]
124 private double _scale = 1.0;
125
126 [NonSerialized]
127 private double4x4 _localToEcef = double4x4.identity;
128
129 [NonSerialized]
130 private double4x4 _ecefToLocal = double4x4.identity;
131
132 [NonSerialized]
133 private bool _isInitialized = false;
134
135 [NonSerialized]
136 private HashSet<CesiumGlobeAnchor> _globeAnchors = new HashSet<CesiumGlobeAnchor>();
137
138 [NonSerialized]
139 private CesiumEllipsoid _ellipsoid = null;
140
141 #endregion
142
156 {
157 get => this._originPlacement;
158 set
159 {
160 this._originPlacement = value;
161 this.MoveOrigin();
162 }
163 }
164
173 {
174 get => this._originAuthority;
175 set
176 {
177 this._originAuthority = value;
178 this.originPlacement = CesiumGeoreferenceOriginPlacement.CartographicOrigin;
179 }
180 }
181
192 public double latitude
193 {
194 get => this._latitude;
195 set
196 {
197 this._latitude = Math.Clamp(value, -90, 90);
198 this.originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;
199 }
200 }
201
212 public double longitude
213 {
214 get => this._longitude;
215 set
216 {
217 this._longitude = Math.Clamp(value, -180, 180);
218 this.originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;
219 }
220 }
221
234 public double height
235 {
236 get => this._height;
237 set
238 {
239 this._height = value;
240 this.originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;
241 }
242 }
243
254 public double ecefX
255 {
256 get => this._ecefX;
257 set
258 {
259 this._ecefX = value;
260 this.originAuthority = CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed;
261 }
262 }
263
274 public double ecefY
275 {
276 get => this._ecefY;
277 set
278 {
279 this._ecefY = value;
280 this.originAuthority = CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed;
281 }
282 }
283
294 public double ecefZ
295 {
296 get => this._ecefZ;
297 set
298 {
299 this._ecefZ = value;
300 this.originAuthority = CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed;
301 }
302 }
303
312 public double scale
313 {
314 get => this._scale;
315 set
316 {
317 this._scale = value;
318 this.MoveOrigin();
319 }
320 }
321
322 public double4x4 localToEcefMatrix
323 {
324 get
325 {
326 this.Initialize();
327 return this._localToEcef;
328 }
329 }
330
331 public double4x4 ecefToLocalMatrix
332 {
333 get
334 {
335 this.Initialize();
336 return this._ecefToLocal;
337 }
338 }
339
344 {
345 get
346 {
347 if (this._ellipsoid == null)
348 {
349 // Make a copy of the ellipsoid ScriptableObject
350 this._ellipsoid = ScriptableObject.CreateInstance<CesiumEllipsoid>();
351 this._ellipsoid.SetRadii((this._ellipsoidOverride ?? CesiumEllipsoid.WGS84).radii);
352 }
353
354 return this._ellipsoid;
355 }
356 set
357 {
358 // Don't set the _ellipsoid field directly; instead, set the ellipsoidOverride,
359 // so that transforms are updated properly. _ellipsoid will be set through that
360 // process.
361 if (this._ellipsoidOverride != value)
362 {
363 this._ellipsoidOverride = value;
364 this.ReloadEllipsoid();
365 }
366 }
367 }
368
372 [Tooltip("An event raised when the georeference origin changes.")]
373 public event Action changed;
374
385 public void SetOriginEarthCenteredEarthFixed(double x, double y, double z)
386 {
387 this._ecefX = x;
388 this._ecefY = y;
389 this._ecefZ = z;
390 this.originAuthority = CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed;
391 }
392
407 public void SetOriginLongitudeLatitudeHeight(double longitude, double latitude, double height)
408 {
409 this._longitude = longitude;
410 this._latitude = latitude;
411 this._height = height;
412 this.originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;
413 }
414
424 public void AddGlobeAnchor(CesiumGlobeAnchor globeAnchor)
425 {
426 this._globeAnchors.Add(globeAnchor);
427 }
428
438 public void RemoveGlobeAnchor(CesiumGlobeAnchor globeAnchor)
439 {
440 this._globeAnchors.Remove(globeAnchor);
441 }
442
461 public void Initialize()
462 {
463 if (!this._isInitialized)
464 {
465 this._isInitialized = true;
466 this.UpdateOtherCoordinates();
467 this.UpdateTransformations();
468 }
469 }
470
474 public void ReloadEllipsoid()
475 {
476 // clear cached ellipsoid so it has to be rebuilt
477 this._ellipsoid = null;
478 this.UpdateTransformations();
479 this.UpdateOtherCoordinates();
480
481 Cesium3DTileset[] tilesets = GetComponentsInChildren<Cesium3DTileset>();
482 foreach (var tileset in tilesets)
483 {
484 tileset.RecreateTileset();
485 }
486 }
487
488 private void UpdateTransformations()
489 {
490 this._localToEcef = this.ComputeLocalToEarthCenteredEarthFixedTransformation();
491 this._ecefToLocal = math.inverse(this._localToEcef);
492 }
493
498 public void MoveOrigin()
499 {
500 if (!this._isInitialized)
501 throw new InvalidOperationException("The origin of a CesiumGeoreference must not be set before its Initialize method is called, either explicitly or via OnEnable.");
502
503 // Scale must be greater than 0
504 if (this._scale < 1e-8)
505 this._scale = 1e-8;
506
507 this.UpdateOtherCoordinates();
508
509 double4x4 oldLocalToEcef = this._localToEcef;
510
511 this.UpdateTransformations();
512
513 if (oldLocalToEcef.Equals(this._localToEcef))
514 {
515 // Origin didn't change meaningfully.
516 return;
517 }
518
519 foreach (CesiumGlobeAnchor anchor in this._globeAnchors)
520 {
521 if (anchor == null)
522 continue;
523
524 anchor.Sync();
525 }
526
527 if (this.changed != null)
528 {
529 this.changed();
530 }
531 }
532
533 private void OnValidate()
534 {
535 if (this._isInitialized)
536 {
537 this.MoveOrigin();
538 }
539 }
540
541 private void OnEnable()
542 {
543 this.Initialize();
544 }
545
546 private void OnDisable()
547 {
548 this._isInitialized = false;
549 }
550
551 private void UpdateOtherCoordinates()
552 {
553 if (this._originAuthority == CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight)
554 {
555 double3 ecef =
556 this.ellipsoid.LongitudeLatitudeHeightToCenteredFixed(
557 new double3(this._longitude, this._latitude, this._height));
558 this._ecefX = ecef.x;
559 this._ecefY = ecef.y;
560 this._ecefZ = ecef.z;
561 }
562 else if (this._originAuthority == CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed)
563 {
564 double3 llh =
565 this.ellipsoid.CenteredFixedToLongitudeLatitudeHeight(
566 new double3(this._ecefX, this._ecefY, this._ecefZ));
567 this._longitude = llh.x;
568 this._latitude = llh.y;
569 this._height = llh.z;
570 }
571 }
572
581 public double3
583 {
584 this.Initialize();
585 return math.mul(this._localToEcef, new double4(unityPosition, 1.0)).xyz;
586 }
587
596 public double3
597 TransformEarthCenteredEarthFixedPositionToUnity(double3 earthCenteredEarthFixed)
598 {
599 this.Initialize();
600 return math.mul(this._ecefToLocal, new double4(earthCenteredEarthFixed, 1.0)).xyz;
601 }
602
611 public double3
613 {
614 this.Initialize();
615 return math.mul(this._localToEcef, new double4(unityDirection, 0.0)).xyz;
616 }
617
626 public double3
627 TransformEarthCenteredEarthFixedDirectionToUnity(double3 earthCenteredEarthFixedDirection)
628 {
629 this.Initialize();
630 return math.mul(this._ecefToLocal, new double4(earthCenteredEarthFixedDirection, 0.0)).xyz;
631 }
632
633 private partial double4x4 ComputeLocalToEarthCenteredEarthFixedTransformation();
634 }
635}
A tileset in the 3D Tiles format.
static CesiumEllipsoid WGS84
Obtain a WGS84 ellipsoid.
partial void SetRadii(double3 newRadii)
Sets the radii of this ellipsoid to the given values.
Controls how global geospatial coordinates are mapped to coordinates in the Unity scene.
double3 TransformEarthCenteredEarthFixedPositionToUnity(double3 earthCenteredEarthFixed)
Transform an Earth-Centered, Earth-Fixed position to Unity coordinates.
double scale
The scale of the globe in the Unity world.
void AddGlobeAnchor(CesiumGlobeAnchor globeAnchor)
Register a globe anchor with this georeference.
double ecefZ
The Earth-Centered, Earth-Fixed Z coordinate of the origin of the coordinate system,...
double3 TransformUnityDirectionToEarthCenteredEarthFixed(double3 unityDirection)
Transform a Unity direction to a direction in Earth-Centered, Earth-Fixed (ECEF) coordinates.
CesiumGeoreferenceOriginAuthority originAuthority
Identifies which set of coordinates authoritatively defines the origin of this georeference.
double ecefX
The Earth-Centered, Earth-Fixed X coordinate of the origin of the coordinate system,...
void SetOriginLongitudeLatitudeHeight(double longitude, double latitude, double height)
Sets the origin of the coordinate system to a particular longitude, latitude, and height.
CesiumGeoreferenceOriginPlacement originPlacement
The placement of this GameObject's origin (coordinate 0,0,0) within the tileset.
double latitude
The latitude of the origin of the coordinate system, in degrees, in the range -90 to 90.
double ecefY
The Earth-Centered, Earth-Fixed Y coordinate of the origin of the coordinate system,...
void Initialize()
Initializes this georeference so that other objects may use it to locate the globe in the world.
CesiumEllipsoid ellipsoid
The CesiumEllipsoid that is referenced.
double longitude
The longitude of the origin of the coordinate system, in degrees, in the range -180 to 180.
double height
The height in the origin of the coordinate system, in meters above the ellipsoid.
double3 TransformUnityPositionToEarthCenteredEarthFixed(double3 unityPosition)
Transform a Unity position to Earth-Centered, Earth-Fixed (ECEF) coordinates.
Action changed
An event raised when the georeference changes.
void MoveOrigin()
Recomputes the coordinate system based on an updated origin.
void RemoveGlobeAnchor(CesiumGlobeAnchor globeAnchor)
Deregisters a globe anchor with this georeference, so the globe anchor will no longer be updated when...
void ReloadEllipsoid()
Called when the ellipsoid override property has changed.
void SetOriginEarthCenteredEarthFixed(double x, double y, double z)
Sets the origin of the coordinate system to particular ecefX, ecefY, ecefZ coordinates in the Earth-C...
double3 TransformEarthCenteredEarthFixedDirectionToUnity(double3 earthCenteredEarthFixedDirection)
Transform an Earth-Centered, Earth-Fixed direction to Unity coordinates.
Anchors this game object to the globe.
void Sync()
Synchronizes the properties of this CesiumGlobeAnchor.
CesiumGeoreferenceOriginPlacement
An enumeration of the possible strategies for placing the origin of a CesiumGeoreference.
@ CartographicOrigin
Use a custom position within the tileset as the GameObject's origin.
@ TrueOrigin
Use the tileset's true origin as the GameObject's origin.
CesiumGeoreferenceOriginAuthority
Identifies the set of the coordinates that authoritatively define the origin of a CesiumGeoreference.
@ EarthCenteredEarthFixed
The CesiumGeoreference.ecefX, CesiumGeoreference.ecefY, and CesiumGeoreference.ecefZ properties autho...
@ LongitudeLatitudeHeight
The CesiumGeoreference.longitude, CesiumGeoreference.latitude, and CesiumGeoreference....