GeoTransforms
A lightweight structure to encapsulate coordinate transforms.文章来源:https://www.toymoban.com/news/detail-506468.html
轻量级的坐标转换类,可以在ECEF、经纬度和UE4坐标之间进行转换。文章来源地址https://www.toymoban.com/news/detail-506468.html
- Earth-Centered, Earth-Fixed (ECEF) coordinates
- Georeferenced coordinates (Latitude/Longitude/Height)
- Unreal coordinates (relative to the unreal world origin)
// Copyright 2020-2021 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeospatial/Ellipsoid.h"
#include <glm/glm.hpp>
/**
* @brief A lightweight structure to encapsulate coordinate transforms.
*
* It encapsulates the conversions between...
* - Earth-Centered, Earth-Fixed (ECEF) coordinates
* - Georeferenced coordinates (Latitude/Longitude/Height)
* - Unreal coordinates (relative to the unreal world origin)
*
*/
class CESIUMRUNTIME_API GeoTransforms {
public:
/**
* @brief Creates a new instance
*/
GeoTransforms()
: _ellipsoid(CesiumGeospatial::Ellipsoid::WGS84),
_center(glm::dvec3(0.0)),
_georeferencedToEcef(1.0),
_ecefToGeoreferenced(1.0),
_ueAbsToEcef(1.0),
_ecefToUeAbs(1.0) {
updateTransforms();
}
/**
* @brief Creates a new instance.
*
* The center position is the position of the origin of the
* local coordinate system that is established by this instance.
*
* @param ellipsoid The ellipsoid to use for the georeferenced coordinates
* @param center The center position.
*/
GeoTransforms(
const CesiumGeospatial::Ellipsoid& ellipsoid,
const glm::dvec3& center)
: _ellipsoid(ellipsoid),
_center(center),
_georeferencedToEcef(1.0),
_ecefToGeoreferenced(1.0),
_ueAbsToEcef(1.0),
_ecefToUeAbs(1.0) {
updateTransforms();
}
/**
* @brief Set the center position of this instance
*
* The center position is the position of the origin of the
* local coordinate system that is established by this instance.
*
* @param center The center position.
*/
void setCenter(const glm::dvec3& center) noexcept;
/**
* @brief Set the ellipsoid of this instance
*
* @param ellipsoid The ellipsoid
*/
void setEllipsoid(const CesiumGeospatial::Ellipsoid& ellipsoid) noexcept;
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height in meters (z) into Earth-Centered, Earth-Fixed
* (ECEF) coordinates.
*/
glm::dvec3 TransformLongitudeLatitudeHeightToEcef(
const glm::dvec3& LongitudeLatitudeHeight) const noexcept;
/**
* Transforms the given Earth-Centered, Earth-Fixed (ECEF) coordinates into
* longitude in degrees (x), latitude in degrees (y), and height in
* meters (z).
*/
glm::dvec3
TransformEcefToLongitudeLatitudeHeight(const glm::dvec3& Ecef) const noexcept;
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height in meters (z) into Unreal world coordinates
* (relative to the floating origin).
*/
glm::dvec3 TransformLongitudeLatitudeHeightToUnreal(
const glm::dvec3& origin,
const glm::dvec3& LongitudeLatitudeHeight) const noexcept;
/**
* Transforms Unreal world coordinates (relative to the floating origin) into
* longitude in degrees (x), latitude in degrees (y), and height in
* meters (z).
*/
glm::dvec3 TransformUnrealToLongitudeLatitudeHeight(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Transforms the given point from Earth-Centered, Earth-Fixed (ECEF) into
* Unreal world coordinates (relative to the floating origin).
*/
glm::dvec3 TransformEcefToUnreal(
const glm::dvec3& origin,
const glm::dvec3& Ecef) const noexcept;
/**
* Transforms the given point from Unreal world coordinates (relative to the
* floating origin) to Earth-Centered, Earth-Fixed (ECEF).
*/
glm::dvec3 TransformUnrealToEcef(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Transforms a rotator from Unreal world to East-North-Up at the given
* Unreal relative world location (relative to the floating origin).
*/
glm::dquat TransformRotatorUnrealToEastNorthUp(
const glm::dvec3& origin,
const glm::dquat& UeRotator,
const glm::dvec3& UeLocation) const noexcept;
/**
* Transforms a rotator from East-North-Up to Unreal world at the given
* Unreal world location (relative to the floating origin).
*/
glm::dquat TransformRotatorEastNorthUpToUnreal(
const glm::dvec3& origin,
const glm::dquat& EnuRotator,
const glm::dvec3& UeLocation) const noexcept;
/**
* Computes the rotation matrix from the local East-North-Up to Unreal at the
* specified Unreal world location (relative to the floating
* origin). The returned transformation works in Unreal's left-handed
* coordinate system.
*/
glm::dmat3 ComputeEastNorthUpToUnreal(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Computes the rotation matrix from the local East-North-Up to
* Earth-Centered, Earth-Fixed (ECEF) at the specified ECEF location.
*/
glm::dmat3 ComputeEastNorthUpToEcef(const glm::dvec3& Ecef) const noexcept;
/*
* GEOREFERENCE TRANSFORMS
*/
/**
* @brief Gets the transformation from the "Georeferenced" reference frame
* defined by this instance to the "Ellipsoid-centered" reference frame (i.e.
* ECEF).
*
* Gets a matrix that transforms coordinates from the "Georeference" reference
* frame defined by this instance to the "Ellipsoid-centered" reference frame,
* which is usually Earth-centered, Earth-fixed. See {@link
* reference-frames.md}.
*/
const glm::dmat4&
GetGeoreferencedToEllipsoidCenteredTransform() const noexcept {
return this->_georeferencedToEcef;
}
/**
* @brief Gets the transformation from the "Ellipsoid-centered" reference
* frame (i.e. ECEF) to the georeferenced reference frame defined by this
* instance.
*
* Gets a matrix that transforms coordinates from the "Ellipsoid-centered"
* reference frame (which is usually Earth-centered, Earth-fixed) to the
* "Georeferenced" reference frame defined by this instance. See {@link
* reference-frames.md}.
*/
const glm::dmat4&
GetEllipsoidCenteredToGeoreferencedTransform() const noexcept {
return this->_ecefToGeoreferenced;
}
/**
* @brief Gets the transformation from the _absolute_ "Unreal World" reference
* frame to the "Ellipsoid-centered" reference frame (i.e. ECEF).
*
* Gets a matrix that transforms coordinates from the absolute "Unreal World"
* reference frame (with respect to the absolute world origin, not the
* floating origin) to the "Ellipsoid-centered" reference frame (which is
* usually Earth-centered, Earth-fixed). See {@link reference-frames.md}.
*/
const glm::dmat4&
GetAbsoluteUnrealWorldToEllipsoidCenteredTransform() const noexcept {
return this->_ueAbsToEcef;
}
/**
* @brief Gets the transformation from the "Ellipsoid-centered" reference
* frame (i.e. ECEF) to the absolute "Unreal World" reference frame.
*
* Gets a matrix that transforms coordinates from the "Ellipsoid-centered"
* reference frame (which is usually Earth-centered, Earth-fixed) to the
* absolute "Unreal world" reference frame (with respect to the absolute world
* origin, not the floating origin). See {@link reference-frames.md}.
*/
const glm::dmat4&
GetEllipsoidCenteredToAbsoluteUnrealWorldTransform() const noexcept {
return this->_ecefToUeAbs;
}
/**
* @brief Computes the normal of the plane tangent to the surface of the
* ellipsoid that is used by this instance, at the provided position.
*
* @param position The cartesian position for which to to determine the
* surface normal.
* @return The normal.
*/
glm::dvec3 ComputeGeodeticSurfaceNormal(const glm::dvec3& position) const {
return _ellipsoid.geodeticSurfaceNormal(position);
}
/**
* Computes the rotation in ellipsoid surface normal between an old position
* and a new position. This rotation is expressed in terms of Unreal world
* coordinates, and can be used to maintain an object's orientation relative
* to the local horizontal as it moves over the globe.
*
* @param oldPosition The old ECEF position that the object moved from.
* @param newPosition The new ECEF position that the object moved to.
* @return The rotation from the ellipsoid surface normal at the old position
* to the ellipsoid surface normal at the new position.
*/
glm::dquat ComputeSurfaceNormalRotation(
const glm::dvec3& oldPosition,
const glm::dvec3& newPosition) const;
/**
* Computes the rotation in ellipsoid surface normal between an old position
* and a new position. This rotation is expressed in terms of Unreal world
* coordinates, and can be used to maintain an object's orientation relative
* to the local horizontal as it moves over the globe.
*
* @param oldPosition The old ECEF position that the object moved from.
* @param newPosition The new ECEF position that the object moved to.
* @return The rotation from the ellipsoid surface normal at the old position
* to the ellipsoid surface normal at the new position.
*/
glm::dquat ComputeSurfaceNormalRotationUnreal(
const glm::dvec3& oldPosition,
const glm::dvec3& newPosition) const;
private:
/**
* Update the derived state (i.e. the matrices) when either
* the center or the ellipsoid has changed.
*/
void updateTransforms() noexcept;
// Modifiable state
CesiumGeospatial::Ellipsoid _ellipsoid;
glm::dvec3 _center;
// Derived state
glm::dmat4 _georeferencedToEcef;
glm::dmat4 _ecefToGeoreferenced;
glm::dmat4 _ueAbsToEcef;
glm::dmat4 _ecefToUeAbs;
};
Usage
glm::dmat4 ecefToUeAbs = glm::dmat4(1.0);
glm::dvec3 center = Cesium3DTilesSelection::getBoundingVolumeCenter(this->_pTileset->getRootTile()->getBoundingVolume());
glm::dmat4 georeferencedToEcef =
CesiumGeospatial::Transforms::eastNorthUpToFixedFrame(center);
glm::dmat4 ecefToGeoreferenced = glm::affineInverse(georeferencedToEcef);
// update ECEF -> UE
ecefToUeAbs = CesiumTransforms::unrealToOrFromCesium *
CesiumTransforms::scaleToUnrealWorld *
ecefToGeoreferenced;
glm::dmat4 AbsToEcef = glm::affineInverse(ecefToUeAbs);
glm::dvec3 ecef= glm::dvec3(AbsToEcef * glm::dvec4(glm::dvec3(
unrealPosition.X,
unrealPosition.Y,
unrealPosition.Z), 1.0));
GeoTransforms trans;
glm::dvec3 BLH=trans.TransformEcefToLongitudeLatitudeHeight(ecef);
参考
- 地心坐标系
- Cesium for UE4 wiki
到了这里,关于Cesium for UE4中的坐标系及其转换(再续)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!