PlaceGeoreferenceOriginHere
Places the georeference origin at the camera’s current location. Rotates the globe so the current longitude/latitude/height of the camera is at the Unreal origin. The camera is also teleported to the Unreal origin.
Warning: Before clicking, ensure that all non-Cesium objects in the persistent level are georeferenced with the “CesiumGeoreferenceComponent” or attached to a “CesiumGlobeAnchorParent”. Ensure that static actors only exist in georeferenced sublevels.
将地理参考原点放置在相机的当前位置。更新视图以便于相机的当前经度/纬度/高度位于虚幻引擎的原点。相机也被传送到虚幻原点。
警告:点击之前,请确保所有非Cesium对象在持久关卡使用“CesiumGeoreferenceComponent”进行地理参考或附加到“CesiumGlobeAnchorParent”。确保只有静态Actors存在于地理参考子关卡。
void ACesiumGeoreference::PlaceGeoreferenceOriginHere() {
#if WITH_EDITOR
// TODO: should we just assume origin rebasing isn't happening since this is
// only editor-mode?
// If this is PIE mode, ignore
if (this->GetWorld()->IsGameWorld()) {
return;
}
// 获取编辑视口
FViewport* pViewport = GEditor->GetActiveViewport();
FViewportClient* pViewportClient = pViewport->GetClient();
FEditorViewportClient* pEditorViewportClient =
static_cast<FEditorViewportClient*>(pViewportClient);
//获取像机的旋转角和位置
FRotationTranslationMatrix fCameraTransform(
pEditorViewportClient->GetViewRotation(),
pEditorViewportClient->GetViewLocation());
//获取世界原点引用
const FIntVector& originLocation = this->GetWorld()->OriginLocation;
// TODO: optimize this, only need to transform the front direction and
// translation
// camera local space to Unreal absolute world
// 像机局部空间转换到绝对空间变换矩阵
glm::dmat4 cameraToAbsolute(
glm::dvec4(
fCameraTransform.M[0][0],
fCameraTransform.M[0][1],
fCameraTransform.M[0][2],
0.0),
glm::dvec4(
fCameraTransform.M[1][0],
fCameraTransform.M[1][1],
fCameraTransform.M[1][2],
0.0),
glm::dvec4(
fCameraTransform.M[2][0],
fCameraTransform.M[2][1],
fCameraTransform.M[2][2],
0.0),
glm::dvec4(
static_cast<double>(fCameraTransform.M[3][0]) +
static_cast<double>(originLocation.X),
static_cast<double>(fCameraTransform.M[3][1]) +
static_cast<double>(originLocation.Y),
static_cast<double>(fCameraTransform.M[3][2]) +
static_cast<double>(originLocation.Z),
1.0));
// camera local space to ECEF
glm::dmat4 cameraToECEF = this->_ueAbsToEcef * cameraToAbsolute;
// Long/Lat/Height camera location (also our new target georeference origin)
// 将像机的UE4局部坐标转换为经纬度
std::optional<CesiumGeospatial::Cartographic> targetGeoreferenceOrigin =
CesiumGeospatial::Ellipsoid::WGS84.cartesianToCartographic(
cameraToECEF[3]);
if (!targetGeoreferenceOrigin) {
// This only happens when the location is too close to the center of the
// Earth.
return;
}
//重新设置地理参考原点BLH
this->_setGeoreferenceOrigin(
glm::degrees(targetGeoreferenceOrigin->longitude),
glm::degrees(targetGeoreferenceOrigin->latitude),
targetGeoreferenceOrigin->height);
// 更新位置后,重新调整像机的姿态和位置 到虚幻原点。
// 同时更新视图。
glm::dmat4 absoluteToRelativeWorld(
glm::dvec4(1.0, 0.0, 0.0, 0.0),
glm::dvec4(0.0, 1.0, 0.0, 0.0),
glm::dvec4(0.0, 0.0, 1.0, 0.0),
glm::dvec4(-originLocation.X, -originLocation.Y, -originLocation.Z, 1.0));
// TODO: check for degeneracy ?
// ECEF -> UE4 相对空间的变换
glm::dmat4 newCameraTransform =
absoluteToRelativeWorld * this->_ecefToUeAbs * cameraToECEF;
glm::dvec3 cameraFront = glm::normalize(newCameraTransform[0]);
glm::dvec3 cameraRight =
glm::normalize(glm::cross(glm::dvec3(0.0, 0.0, 1.0), cameraFront));
glm::dvec3 cameraUp = glm::normalize(glm::cross(cameraFront, cameraRight));
//更新视口变换变换矩阵
pEditorViewportClient->SetViewRotation(
FMatrix(
FVector(cameraFront.x, cameraFront.y, cameraFront.z),
FVector(cameraRight.x, cameraRight.y, cameraRight.z),
FVector(cameraUp.x, cameraUp.y, cameraUp.z),
FVector(0.0f, 0.0f, 0.0f))
.Rotator());
pEditorViewportClient->SetViewLocation(
FVector(-originLocation.X, -originLocation.Y, -originLocation.Z));
#endif
}