【问题标题】:FBXSDK, using Quaternions to set rotation keys?FBXSDK,使用四元数设置旋转键?
【发布时间】:2018-05-24 23:54:24
【问题描述】:

我正在尝试使用 Autodesk FBXSDK 编写文件保存应用程序。我使用欧拉旋转可以正常工作,但我需要更新它以使用四元数。

相关函数为:

bool CreateScene(FbxScene* pScene, double lFocalLength, int startFrame)
{
    //Create Camera
    FbxNode* lMyCameraNode = FbxNode::Create(pScene, "p_camera");
    //connect camera node to root node
    FbxNode* lRootNode = pScene->GetRootNode();
    lRootNode->ConnectSrcObject(lMyCameraNode);
    FbxCamera* lMyCamera = FbxCamera::Create(pScene, "Root_camera");
    lMyCameraNode->SetNodeAttribute(lMyCamera);


    // Create an animation stack
    FbxAnimStack* myAnimStack = FbxAnimStack::Create(pScene, "My stack");

    // Create the base layer (this is mandatory)
    FbxAnimLayer* pAnimLayer = FbxAnimLayer::Create(pScene, "Layer0");

    myAnimStack->AddMember(pAnimLayer);

    // Get the camera’s curve node for local translation.

    FbxAnimCurveNode* myAnimCurveNodeRot = lMyCameraNode->LclRotation.GetCurveNode(pAnimLayer, true);

    //create curve nodes
    FbxAnimCurve* myRotXCurve = NULL;   
    FbxAnimCurve* myRotYCurve = NULL;
    FbxAnimCurve* myRotZCurve = NULL;

    FbxTime lTime;                         // For the start and stop keys.  int lKeyIndex = 0;                // Index for the keys that define the curve



    // Get the animation curve for local rotation of the camera.
    myRotXCurve = lMyCameraNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
    myRotYCurve = lMyCameraNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
    myRotZCurve = lMyCameraNode->LclRotation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true);


    //This to add keys, per frame.  
    float frameNumber = startFrame;

    for (int i = 0; i < rec.size(); i++)
    {
        lTime.SetFrame(frameNumber);  //frame number

        //rx
        lKeyIndex = myRotXCurve->KeyAdd(lTime);
        myRotXCurve->KeySet(lKeyIndex, lTime, recRotX[i], FbxAnimCurveDef::eInterpolationLinear);

        //ry
        lKeyIndex = myRotYCurve->KeyAdd(lTime);
        myRotYCurve->KeySet(lKeyIndex, lTime, recRotY[i], FbxAnimCurveDef::eInterpolationLinear);

        //rz
        lKeyIndex = myRotZCurve->KeyAdd(lTime);
        myRotZCurve->KeySet(lKeyIndex, lTime, recRotZ[i], FbxAnimCurveDef::eInterpolationLinear);

        frameNumber += 1;

    }

    return true;
}

理想情况下,我希望在这里传入四元数数据,而不是欧拉 x、y、z 值。 fbxsdk可以做到这一点吗?还是我需要先转换我的四元数数据,然后继续传入欧拉? 谢谢。

【问题讨论】:

    标签: c++ quaternions autodesk fbx


    【解决方案1】:

    接受的答案不起作用。虽然the documentation 绝对暗示应该这样做,

    创建一个等效于当前四元数的 Euler XYZ。

    一位 Autodesk 员工 claims 不是

    DecomposeSphericalXYZ 不会转换为欧拉角

    我的测试证实了这一点。在当前的 FBX SDK 中,至少有两种相对简单的方法可以将 quat 转换为他们所谓的 euler 或适合 LclRotation 的东西。首先是通过FbxAMatrix

        FbxQuaternion fq = ...;
        FbxAMatrix fa;
        fa.SetQ(fq);
        FbxVector4 fe = fa.GetR();
    

    第二个是通过FbxVector::SetXYZ

        FbxVector4 fe2;
        fe2.SetXYZ(fq);
    

    我已经成功地从这两种方法中的 XYZ 旋转序列 → 四元数 → 欧拉出发,并检索到相同的旋转序列。当我使用DecomposeSphericalXYZ 时,我得到的FbxVector4 略有不同。我还没有试图弄清楚“球坐标中的欧拉”是什么意思。

    【讨论】:

      【解决方案2】:

      您总是需要回到欧拉角,因为您只能获得 XYZ 旋转的动画曲线。您唯一可以控制的是轮换顺序。

      但是,您可以使用 FbxQuaternion 进行计算,然后使用 .DecomposeSphericalXYZ() 获取 XYZ 欧拉角。

      【讨论】:

      • 谢谢!我最终使用:Eigen::Quaternionf q(rw, rx, ry, rz); auto euler = q.toRotationMatrix().eulerAngles(0, 1, 2); //roll, pitch, yaw 但也会看看.DecomposeSphericalXYZ()
      • 再次嗨,使用 Eigen 仍然给我奇怪的欧拉翻转,所以我正在调查你的答案。 DecomposeSphericalXYZ 给了我其他欧拉问题,在不同的轴上旋转而不是预期。我正在使用:fbxsdk::FbxQuaternion fbxQuat(rx, ry, rz, rw); fbxsdk::FbxVector4 fbxeuler = fbxQuat.DecomposeSphericalXYZ();,然后将前三个值 `fbxeuler []0 作为 X,fbxeuler [1] 作为 Y,fbxeuler [2] 作为 Z。这是正确的吗?再次感谢!
      • 是的,应该是这样。你能发布一些代码来显示旋转应该如何以及它是如何出现的吗?角度分解的顺序可能存在一些差异。另外,请检查您是否在 FBX 中使用 XYZ 旋转顺序
      猜你喜欢
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多