Skip to content

Commit

Permalink
Merge pull request #493 from CesiumGS/true-origin-georeference
Browse files Browse the repository at this point in the history
Add 'True Origin' placement mode
  • Loading branch information
kring authored Aug 29, 2024
2 parents b0023d7 + 9bb41c0 commit 2afed5e
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
##### Additions :tada:

- Editor builds for macOS now target macOS 10.15+. Previously, macOS 12.7+ was required.
- Added `originPlacement` property to `CesiumGeoreference` to toggle between "Cartographic Origin" and "True Origin" reference modes. Whereas "Cartographic Origin" is the default for georeferenced tilesets, "True Origin" may be used for non-georeferenced tilesets centered at the origin.

##### Fixes :wrench:

Expand Down
85 changes: 67 additions & 18 deletions Editor/CesiumGeoreferenceEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ public class CesiumGeoreferenceEditor : Editor
{
private CesiumGeoreference _georeference;

private SerializedProperty _originPlacement;

// Converts the SerializedProperty's value to the CesiumGeoreferenceOriginPlacement
// enum it corresponds to, for convenience.
internal CesiumGeoreferenceOriginPlacement originPlacement
{
get
{
return (CesiumGeoreferenceOriginPlacement)
this._originPlacement.enumValueIndex;
}
}

private SerializedProperty _originAuthority;

// Converts the SerializedProperty's value to the CesiumGeoreferenceOriginAuthority
Expand Down Expand Up @@ -37,6 +50,8 @@ private void OnEnable()
this._georeference = (CesiumGeoreference)this.target;

this._ellipsoidOverride = this.serializedObject.FindProperty("_ellipsoidOverride");
this._originPlacement =
this.serializedObject.FindProperty("_originPlacement");
this._originAuthority =
this.serializedObject.FindProperty("_originAuthority");

Expand All @@ -57,24 +72,26 @@ public override void OnInspectorGUI()

DrawInspectorButtons();
EditorGUILayout.Space(5);

this.DrawEllipsoidOverrideProperty();
EditorGUILayout.Space(5);
this.DrawScaleProperty();
EditorGUILayout.Space(5);
this.DrawOriginAuthorityProperty();

this.DrawOriginModeProperties();
EditorGUILayout.Space(5);
this.DrawLongitudeLatitudeHeightProperties();
EditorGUILayout.Space(5);
this.DrawEarthCenteredEarthFixedProperties();
EditorGUILayout.Space(5);

this.DrawScaleProperty();
this.DrawEllipsoidOverrideProperty();

this.serializedObject.ApplyModifiedProperties();
}

private void DrawInspectorButtons()
{
// Don't modify the georeference if the editor is in play mode.
EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
EditorGUI.BeginDisabledGroup(
EditorApplication.isPlaying
|| this.originPlacement != CesiumGeoreferenceOriginPlacement.CartographicOrigin);

GUILayout.BeginHorizontal();
GUIContent placeOriginHereContent = new GUIContent(
Expand All @@ -98,30 +115,67 @@ private void DrawInspectorButtons()
"Creates a child GameObject with a \"CesiumSubScene\" component whose origin " +
"is set to the camera's current location. A \"CesiumSubScene\" describes a " +
"corresponding world location that can be jumped to, and only one sub-scene " +
"can be worked on in the editor at a time.");
"can be worked on in the editor at a time." +
"\n\n" +
"This is disabled when \"Origin Placement\" is set to \"True Origin\".");
if (GUILayout.Button("Create Sub-Scene Here"))
{
CesiumEditorUtility.CreateSubScene(this._georeference);
}

GUILayout.EndHorizontal();

EditorGUI.EndDisabledGroup();
}

private void DrawOriginModeProperties()
{
GUILayout.Label("Origin Mode", EditorStyles.boldLabel);

GUIContent originPlacementContent = new GUIContent(
"Placement",
"The placement of this GameObject's origin (0,0,0) within the tileset." +
"\n\n" +
"3D Tiles tilesets often use Earth-centered, Earth-fixed coordinates, such that " +
"the tileset content is in a small bounding volume 6-7 million meters " +
"(the radius of the Earth) away from the coordinate system origin. This property " +
"allows an alternative position, other than the tileset's true origin, to be " +
"treated as the origin for the purpose of this GameObject. Using this property will " +
"preserve vertex precision (and thus avoid jittering) much better than setting the " +
"GameObject's Transform property.");
EditorGUILayout.PropertyField(this._originPlacement, originPlacementContent);

EditorGUI.BeginDisabledGroup(
this.originPlacement != CesiumGeoreferenceOriginPlacement.CartographicOrigin);

GUIContent originAuthorityContent = new GUIContent(
"Authority",
"The set of coordinates that authoritatively define the origin of " +
"this georeference.");
EditorGUILayout.PropertyField(this._originAuthority, originAuthorityContent);

EditorGUI.EndDisabledGroup();
}

private void DrawEllipsoidOverrideProperty()
{
EditorGUI.BeginDisabledGroup(
this.originPlacement != CesiumGeoreferenceOriginPlacement.CartographicOrigin);

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.");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(this._ellipsoidOverride, ellipsoidOverrideContent);
if(EditorGUI.EndChangeCheck())
if (EditorGUI.EndChangeCheck())
{
this.serializedObject.ApplyModifiedProperties();
this._georeference.ReloadEllipsoid();
}

EditorGUI.EndDisabledGroup();
}

private void DrawScaleProperty()
Expand All @@ -135,19 +189,12 @@ private void DrawScaleProperty()
EditorGUILayout.PropertyField(this._scale, scaleContent);
}

private void DrawOriginAuthorityProperty()
{
GUIContent originAuthorityContent = new GUIContent(
"Origin Authority",
"The set of coordinates that authoritatively define the origin of " +
"this georeference.");
EditorGUILayout.PropertyField(this._originAuthority, originAuthorityContent);
}

private void DrawLongitudeLatitudeHeightProperties()
{
CesiumGeoreferenceOriginPlacement placement = this.originPlacement;
CesiumGeoreferenceOriginAuthority authority = this.originAuthority;
EditorGUI.BeginDisabledGroup(
placement != CesiumGeoreferenceOriginPlacement.CartographicOrigin ||
authority != CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight);

GUILayout.Label(
Expand Down Expand Up @@ -187,8 +234,10 @@ private void DrawLongitudeLatitudeHeightProperties()

private void DrawEarthCenteredEarthFixedProperties()
{
CesiumGeoreferenceOriginPlacement placement = this.originPlacement;
CesiumGeoreferenceOriginAuthority authority = this.originAuthority;
EditorGUI.BeginDisabledGroup(
placement != CesiumGeoreferenceOriginPlacement.CartographicOrigin ||
authority != CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed);

GUILayout.Label(
Expand Down
117 changes: 99 additions & 18 deletions Runtime/CesiumGeoreference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@

namespace CesiumForUnity
{
/// <summary>
/// An enumeration of the possible strategies for placing the origin of a <see cref="CesiumGeoreference"/>.
/// </summary>
public enum CesiumGeoreferenceOriginPlacement
{
/// <summary>
/// Use the tileset's true origin as the GameObject's origin.
/// </summary>
/// <remarks>
/// For georeferenced tilesets, this usually means the GameObject's origin will be
/// at the center of the Earth, which is not recommended. For a non-georeferenced
/// tileset, however, such as a detailed building with a local origin, putting the
/// GameObject's origin at the same location as the tileset's origin can be useful.
/// </remarks>
TrueOrigin,
/// <summary>
/// Use a custom position within the tileset as the GameObject's origin. The
/// position is expressed as cartographic coordinates determined by the
/// <see cref="CesiumGeoreference.originAuthority"/>, and that position within
/// the tileset will be at coordinate (0,0,0) in the GameObject's coordinate system.
/// </summary>
CartographicOrigin
}

/// <summary>
/// Identifies the set of the coordinates that authoritatively define
/// the origin of a <see cref="CesiumGeoreference"/>.
Expand Down Expand Up @@ -68,6 +92,9 @@ public partial class CesiumGeoreference : MonoBehaviour
[SerializeField]
private CesiumEllipsoid _ellipsoidOverride = null;

[SerializeField]
private CesiumGeoreferenceOriginPlacement _originPlacement = CesiumGeoreferenceOriginPlacement.CartographicOrigin;

[SerializeField]
private CesiumGeoreferenceOriginAuthority _originAuthority = CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight;

Expand Down Expand Up @@ -113,26 +140,55 @@ public partial class CesiumGeoreference : MonoBehaviour

#endregion

/// <summary>
/// The placement of this GameObject's origin (coordinate 0,0,0) within the tileset.
/// </summary>
/// <remarks>
/// 3D Tiles tilesets often use Earth-centered, Earth-fixed coordinates, such
/// that the tileset content is in a small bounding volume 6-7 million meters
/// (the radius of the Earth) away from the coordinate system origin. This
/// property allows an alternative position, other than the tileset's true
/// origin, to be treated as the origin for the purpose of this GameObject. Using
/// this property will preserve vertex precision (and thus avoid jittering)
/// much better than setting the GameObject's Transform property.
/// </remarks>
public CesiumGeoreferenceOriginPlacement originPlacement
{
get => this._originPlacement;
set
{
this._originPlacement = value;
this.MoveOrigin();
}
}

/// <summary>
/// Identifies which set of coordinates authoritatively defines the origin
/// of this georeference.
/// </summary>
/// <remarks>
/// Setting this property changes the <see cref="originPlacement"/> accordingly.
/// </remarks>
public CesiumGeoreferenceOriginAuthority originAuthority
{
get => this._originAuthority;
set
{
this._originAuthority = value;
this.MoveOrigin();
this.originPlacement = CesiumGeoreferenceOriginPlacement.CartographicOrigin;
}
}

/// <summary>
/// The latitude of the origin of the coordinate system, in degrees, in the range -90 to 90.
/// This property is ignored unless <see cref="originAuthority"/> is
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double latitude
{
get => this._latitude;
Expand All @@ -145,10 +201,14 @@ public double latitude

/// <summary>
/// The longitude of the origin of the coordinate system, in degrees, in the range -180 to 180.
/// This property is ignored unless <see cref="originAuthority"/> is
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double longitude
{
get => this._longitude;
Expand All @@ -162,11 +222,15 @@ public double longitude
/// <summary>
/// The height in the origin of the coordinate system, in meters above the ellipsoid. Do not
/// confuse this with a geoid height or height above mean sea level, which can be tens of
/// meters higher or lower depending on where in the world the object is located. This
/// property is ignored unless <see cref="originAuthority"/> is
/// meters higher or lower depending on where in the world the object is located.
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.LongitudeLatitudeHeight"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double height
{
get => this._height;
Expand All @@ -179,10 +243,14 @@ public double height

/// <summary>
/// The Earth-Centered, Earth-Fixed X coordinate of the origin of the coordinate system, in meters.
/// This property is ignored unless <see cref="originAuthority"/> is
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double ecefX
{
get => this._ecefX;
Expand All @@ -195,10 +263,14 @@ public double ecefX

/// <summary>
/// The Earth-Centered, Earth-Fixed Y coordinate of the origin of the coordinate system, in meters.
/// This property is ignored unless <see cref="originAuthority"/> is
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double ecefY
{
get => this._ecefY;
Expand All @@ -211,10 +283,14 @@ public double ecefY

/// <summary>
/// The Earth-Centered, Earth-Fixed Z coordinate of the origin of the coordinate system, in meters.
/// This property is ignored unless <see cref="originAuthority"/> is
/// </summary>
/// <remarks>
/// This property only takes effect if <see cref="CesiumGeoreference.originPlacement"/> is set to
/// <see cref="CesiumGeoreferenceOriginPlacement.CartographicOrigin"/> and
/// <see cref="originAuthority"/> is set to
/// <see cref="CesiumGeoreferenceOriginAuthority.EarthCenteredEarthFixed"/>.
/// Setting this property changes the <see cref="originAuthority"/> accordingly.
/// </summary>
/// </remarks>
public double ecefZ
{
get => this._ecefZ;
Expand All @@ -227,10 +303,12 @@ public double ecefZ

/// <summary>
/// The scale of the globe in the Unity world. If this value is 0.5, for example, one
/// meter on the globe occupies half a meter in the Unity world. The globe can also
/// be scaled by modifying the georeference's Transform, but setting this property instead
/// will do a better job of preserving precision.
/// meter on the globe occupies half a meter in the Unity world.
/// </summary>
/// <remarks>
/// The globe can also be scaled by modifying the georeference's Transform, but setting
/// this property instead will do a better job of preserving precision.
/// </remarks>
public double scale
{
get => this._scale;
Expand Down Expand Up @@ -259,6 +337,9 @@ public double4x4 ecefToLocalMatrix
}
}

/// <summary>
/// The <see cref="CesiumEllipsoid"/> that is referenced.
/// </summary>
public CesiumEllipsoid ellipsoid
{
get
Expand Down Expand Up @@ -391,7 +472,7 @@ public void ReloadEllipsoid()
this.UpdateOtherCoordinates();

Cesium3DTileset[] tilesets = GetComponentsInChildren<Cesium3DTileset>();
foreach(var tileset in tilesets)
foreach (var tileset in tilesets)
{
tileset.RecreateTileset();
}
Expand Down
Loading

0 comments on commit 2afed5e

Please sign in to comment.