FBXSDK,使用四元数设置旋转键?
FBXSDK, using Quaternions to set rotation keys?
我正在尝试使用 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 可以吗?或者我需要先转换我的四元数数据,然后继续传入欧拉?
谢谢。
你总是需要回到欧拉角,因为你只能得到 XYZ 旋转的动画曲线。您唯一可以控制的是旋转顺序。
但是,您可以使用 FbxQuaternion 进行计算,然后使用 .DecomposeSphericalXYZ() 获得 XYZ 欧拉角。
已接受的答案无效。虽然 the documentation 肯定暗示它应该,
Create an Euler XYZ equivalent to the current quaternion.
一名 Autodesk 员工claims,但它没有
DecomposeSphericalXYZ does not convert to Euler angles
我的测试证实了这一点。在当前的 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
。我还没有试图弄清楚“球坐标系中的欧拉”是什么意思。
我正在尝试使用 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 可以吗?或者我需要先转换我的四元数数据,然后继续传入欧拉? 谢谢。
你总是需要回到欧拉角,因为你只能得到 XYZ 旋转的动画曲线。您唯一可以控制的是旋转顺序。
但是,您可以使用 FbxQuaternion 进行计算,然后使用 .DecomposeSphericalXYZ() 获得 XYZ 欧拉角。
已接受的答案无效。虽然 the documentation 肯定暗示它应该,
Create an Euler XYZ equivalent to the current quaternion.
一名 Autodesk 员工claims,但它没有
DecomposeSphericalXYZ does not convert to Euler angles
我的测试证实了这一点。在当前的 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
。我还没有试图弄清楚“球坐标系中的欧拉”是什么意思。