UE5欧拉角转四元数

UE5欧拉角转四元数

码农世界 2024-05-18 前端 61 次浏览 0个评论

 TQuat

@/p/sx/UnrealEngine/UnrealEngine/Engine/Source/Runtime/Core/Public/Math/Quat.h
FORCEINLINE TQuat::TQuat(const TRotator& R)
    *this = R.Quaternion();
@/p/sx/UnrealEngine/UnrealEngine/Engine/Source/Runtime/Core/Public/Math/Rotator.h
@/p/sx/UnrealEngine/UnrealEngine/Engine/Source/Runtime/Core/Private/Math/UnrealMath.cpp
        FQuat4d FRotator3d::Quaternion() const
        DiagnosticCheckNaN();
    
    #if PLATFORM_ENABLE_VECTORINTRINSICS
        const VectorRegister4Double Angles = MakeVectorRegisterDouble(Pitch, Yaw, Roll, 0.0);
        const VectorRegister4Double AnglesNoWinding = VectorMod360(Angles);
        const VectorRegister4Double HalfAngles = VectorMultiply(AnglesNoWinding, GlobalVectorConstants::DOUBLE_DEG_TO_RAD_HALF);
    
        VectorRegister4Double SinAngles, CosAngles;
        VectorSinCos(&SinAngles, &CosAngles, &HalfAngles);
    
        // Vectorized conversion, measured 20% faster than using scalar version after VectorSinCos.
        // Indices within VectorRegister (for shuffles): P=0, Y=1, R=2
        const VectorRegister4Double SR = VectorReplicate(SinAngles, 2);
        const VectorRegister4Double CR = VectorReplicate(CosAngles, 2);
    
        const VectorRegister4Double SY_SY_CY_CY_Temp = VectorShuffle(SinAngles, CosAngles, 1, 1, 1, 1);
    
        const VectorRegister4Double SP_SP_CP_CP = VectorShuffle(SinAngles, CosAngles, 0, 0, 0, 0);
        const VectorRegister4Double SY_CY_SY_CY = VectorShuffle(SY_SY_CY_CY_Temp, SY_SY_CY_CY_Temp, 0, 2, 0, 2);
    
        const VectorRegister4Double CP_CP_SP_SP = VectorShuffle(CosAngles, SinAngles, 0, 0, 0, 0);
        const VectorRegister4Double CY_SY_CY_SY = VectorShuffle(SY_SY_CY_CY_Temp, SY_SY_CY_CY_Temp, 2, 0, 2, 0);
    
        const uint64 Neg = uint64(1) << 63;
        const uint64 Pos = uint64(0);
        const VectorRegister4Double SignBitsLeft = MakeVectorRegisterDoubleMask(Pos, Neg, Pos, Pos);
        const VectorRegister4Double SignBitsRight = MakeVectorRegisterDoubleMask(Neg, Neg, Neg, Pos);
        const VectorRegister4Double LeftTerm = VectorBitwiseXor(SignBitsLeft, VectorMultiply(CR, VectorMultiply(SP_SP_CP_CP, SY_CY_SY_CY)));
        const VectorRegister4Double RightTerm = VectorBitwiseXor(SignBitsRight, VectorMultiply(SR, VectorMultiply(CP_CP_SP_SP, CY_SY_CY_SY)));
    
        const VectorRegister4Double Result = VectorAdd(LeftTerm, RightTerm);
        FQuat4d RotationQuat = FQuat4d::MakeFromVectorRegister(Result);
    #else
        const double DEG_TO_RAD = UE_DOUBLE_PI / (180.0);
        const double RADS_DIVIDED_BY_2 = DEG_TO_RAD / 2.0;
        double SP, SY, SR;
        double CP, CY, CR;
    
        const double PitchNoWinding = FMath::Fmod(Pitch, 360.0);
        const double YawNoWinding = FMath::Fmod(Yaw, 360.0);
        const double RollNoWinding = FMath::Fmod(Roll, 360.0);
    
        FMath::SinCos(&SP, &CP, PitchNoWinding * RADS_DIVIDED_BY_2);
        FMath::SinCos(&SY, &CY, YawNoWinding * RADS_DIVIDED_BY_2);
        FMath::SinCos(&SR, &CR, RollNoWinding * RADS_DIVIDED_BY_2);
    
        FQuat4d RotationQuat;
        RotationQuat.X = CR * SP * SY - SR * CP * CY;
        RotationQuat.Y = -CR * SP * CY - SR * CP * SY;
        RotationQuat.Z = CR * CP * SY - SR * SP * CY;
        RotationQuat.W = CR * CP * CY + SR * SP * SY;
    #endif // PLATFORM_ENABLE_VECTORINTRINSICS
    
    #if ENABLE_NAN_DIAGNOSTIC || DO_CHECK
        // Very large inputs can cause NaN's. Want to catch this here
        if (RotationQuat.ContainsNaN())
        {
            logOrEnsureNanError(TEXT("Invalid input %s to FRotator::Quaternion - generated NaN output: %s"), *ToString(), *RotationQuat.ToString());
            RotationQuat = FQuat4d::Identity;
            FDebug::DumpStackTraceToLog(ELogVerbosity::Warning);
        }
    #endif
    
        return RotationQuat;        
        

转载请注明来自码农世界,本文标题:《UE5欧拉角转四元数》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,61人围观)参与讨论

还没有评论,来说两句吧...

Top