UE5欧拉角转四元数

 TQuat

@/p/sx/UnrealEngine/UnrealEngine/Engine/Source/Runtime/Core/Public/Math/Quat.h
FORCEINLINE TQuat<T>::TQuat(const TRotator<T>& 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;        
        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛文旺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值