Hello! Sometimes I am noticing an issue and can’t figure out how to properly replicate it.
Exception raises in Runtime/Core/Public/Math/Quat.h:
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
// Make sure the Rotation part of the Matrix is unit length.
// Changed to this (same as RemoveScaling) from RotDeterminant as using two different ways of checking unit length matrix caused inconsistency.
if (!ensure((FMath::Abs(1.f - M.GetScaledAxis(EAxis::X).SizeSquared()) <= UE_KINDA_SMALL_NUMBER) && (FMath::Abs(1.f - M.GetScaledAxis(EAxis::Y).SizeSquared()) <= UE_KINDA_SMALL_NUMBER) && (FMath::Abs(1.f - M.GetScaledAxis(EAxis::Z).SizeSquared()) <= UE_KINDA_SMALL_NUMBER)))
{
*this = TQuat<T>::Identity;
return;
}
#endif
This condition raises in this code from “Math/TransformVectorized.h”:
void SetFromMatrix(const TMatrix<T>& InMatrix)
{
TMatrix<T> M = InMatrix;
// Get the 3D scale from the matrix
TVector<T> InScale = M.ExtractScaling();
Scale3D = VectorLoadFloat3_W0(&InScale);
// If there is negative scaling going on, we handle that here
if(InMatrix.Determinant() < 0.f)
{
// Assume it is along X and modify transform accordingly.
// It doesn't actually matter which axis we choose, the 'appearance' will be the same
Scale3D = VectorMultiply(Scale3D, (TransformVectorRegister)GlobalVectorConstants::FloatMinus1_111 );
M.SetAxis(0, -M.GetScaledAxis( EAxis::X ));
}
TQuat<T> InRotation = TQuat<T>(M); // <=== HERE (!)
Rotation = VectorLoadAligned(&InRotation);
TVector<T> InTranslation = InMatrix.GetOrigin();
Translation = VectorLoadFloat3_W0(&InTranslation);
// Normalize rotation
Rotation = VectorNormalizeQuaternion(Rotation);
}
Just before that:
FORCEINLINE explicit TTransform(const TMatrix<T>& InMatrix)
{
SetFromMatrix(InMatrix); // <=== HERE (!)
DiagnosticCheckNaN_All();
}
It happens here:
void UCesiumGlobeAnchorComponent::_updateFromNativeGlobeAnchor(
const CesiumGeospatial::GlobeAnchor& nativeAnchor) {
this->ActorToEarthCenteredEarthFixedMatrix =
VecMath::createMatrix(nativeAnchor.getAnchorToFixedTransform());
this->_actorToECEFIsValid = true;
// Update the Unreal relative transform
ACesiumGeoreference* pGeoreference = this->ResolveGeoreference();
if (IsValid(pGeoreference)) {
glm::dmat4 anchorToLocal = nativeAnchor.getAnchorToLocalTransform(
pGeoreference->GetCoordinateSystem());
this->_setCurrentRelativeTransform(
FTransform(VecMath::createMatrix(anchorToLocal))); // <=== HERE (!)
} else {
this->_lastRelativeTransformIsValid = false;
}
}
Which actually raises from here:
// Update with the new ECEF transform, also rotating based on the new position
// if desired.
CesiumGeospatial::GlobeAnchor nativeAnchor =
this->_createOrUpdateNativeGlobeAnchorFromECEF(Value);
this->_updateFromNativeGlobeAnchor(nativeAnchor); // <=== HERE (!)
In order not to increase this topic further, I will skip some other callers.
The “main” point before exception from my code is here
GeoComponent->MoveToLongitudeLatitudeHeight(FVector(Longitude, Latitude, Height));
GeoComponent is UCesiumGlobeAnchorComponent* and created with:
GeoComponent = CreateDefaultSubobject<UCesiumGlobeAnchorComponent>(TEXT("CesiumGlobeAnchorComponent"));
What could be the reason for this behaviour? It doesn’t happen all the time, but sometimes.
I guess this person had the same issue, but there were no answers for that:
p.s. Unreal 5.3, built from source on linux, cesium 2.4.1. Cesium is placed in Plugins inside Engine folder