代码之家  ›  专栏  ›  技术社区  ›  anti

FBXSDK,使用四元数设置旋转关键点?

  •  0
  • anti  · 技术社区  · 7 年前

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

    相关功能为:

    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;
    }
    

    理想情况下,我希望在这里传递四元数数据,而不是euler x、y、z值。fbxsdk是否有这种可能?或者我需要先转换我的四元数数据,然后继续传递EULER吗? 非常感谢。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Anna-Chiara Bellini    7 年前

    始终需要返回到Euler角度,因为只能获取XYZ旋转的动画曲线。唯一可以控制的是旋转顺序。

    但是,您可以使用FbxQuaternion进行计算,然后使用。分解sphericalxyz()以获得XYZ Euler角度。

        2
  •  0
  •   Paul Du Bois    3 年前

    公认的答案无效。虽然 the documentation 这肯定意味着它应该,

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

    Autodesk员工 claims 事实并非如此

    分解sphericalxyz不转换为欧拉角

    我的测试证明了这一点。在当前的FBX SDK中,至少有两种相对简单的方法可以将quat转换为他们所称的euler,或转换为适合LCL旋转的对象。首先是via FbxAMatrix

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

    第二个是via FbxVector::SetXYZ

        FbxVector4 fe2;
        fe2.SetXYZ(fq);
    

    我已经成功地从两种方法的XYZ旋转序列四元数euler中提取了相同的旋转序列。当我使用 DecomposeSphericalXYZ 我有点不同 FbxVector4 . 我还没有试着弄明白“球坐标中的欧拉”是什么意思。