Matrix 将全局层次旋转转换为局部旋转和反向旋转
我有一个分层框架,其中平移和旋转在全局空间中表示。我需要将骨架转换为局部坐标,然后再转换回来。我对翻译没有问题,但我似乎无法使旋转工作 最初,我有旋转矩阵,但我可以轻松地将它们转换为Euler或四元数,并尝试使用它们。我正在使用Irrlicht引擎数学库 因此,我的代码遍历每个骨骼,只要骨骼有下一个父骨骼,就应用转换 从全球到本地:Matrix 将全局层次旋转转换为局部旋转和反向旋转,matrix,rotation,global,local,quaternions,Matrix,Rotation,Global,Local,Quaternions,我有一个分层框架,其中平移和旋转在全局空间中表示。我需要将骨架转换为局部坐标,然后再转换回来。我对翻译没有问题,但我似乎无法使旋转工作 最初,我有旋转矩阵,但我可以轻松地将它们转换为Euler或四元数,并尝试使用它们。我正在使用Irrlicht引擎数学库 因此,我的代码遍历每个骨骼,只要骨骼有下一个父骨骼,就应用转换 从全球到本地: for(; iter != absolutePose.end(); iter++) { if(hierarchy->find(iter->bon
for(; iter != absolutePose.end(); iter++)
{
if(hierarchy->find(iter->boneID) != hierarchy->end())
{
BoneID parentNodeID = hierarchy[iter->boneID];
relativePose[iter->boneID].position.X = iter->position.X - absolutePose[parentNodeId].position.X;
relativePose[iter->boneID].position.Y = iter->position.Y - absolutePose[parentNodeId].position.Y;
relativePose[iter->boneID].position.Z = iter->position.Z - absolutePose[parentNodeId].position.Z;
////Rotation Part/////////
float pq[4] ={0.0,0.0,0.0,0.0};
MatrixToQuaternion(absolutePose[parentNodeId].orientation, pq);
irr::core::quaternion quat(q[0],q[1],q[2],q[3]);
irr::core::quaternion parentquat(pq[0],pq[1],pq[2],pq[3]);
quat = quat.makeInverse();
quat = quat*parentquat;
float newQuat[4] = {quat.X, quat.Y, quat.Z, quat.W};
QuaternionToMatrix(newQuat,relativePose[iter->first].orientation);
}
else // top bone
{
relativePose[iter->boneID].position.X = iter->position.X;
relativePose[iter->boneID].position.Y = iter->position.Y;
relativePose[iter->boneID].position.Z = iter->position.Z;
relativePose[iter->boneID].orientation = iter->second.orientation;
}
}
然后从本地到全球:
for(; iter != relativePose.end(); iter++)
{
absolutePose[iter->boneID].position.position = iter->position;
auto nextParent = hierarchy->find(iter->boneID);
while(nextParent != hierarchy->end())
{
absolutePose[iter->boneID].position.X += relativePose[nextParent->boneID].position.X;
absolutePose[iter->boneID].position.Y += relativePose[nextParent->boneID].position.Y;
absolutePose[iter->boneID].position.Z += relativePose[nextParent->boneID].position.Z;
////Rotation part///
float q[4] ={0.0,0.0,0.0,0.0};
MatrixToQuaternion(relativePose[iter->boneID].orientation, q);
float pq[4] ={0.0,0.0,0.0,0.0};
MatrixToQuaternion(relativePose[nextParent->boneID].orientation, pq);
irr::core::quaternion quat(q[0],q[1],q[2],q[3]);
irr::core::quaternion parentquat(pq[0],pq[1],pq[2],pq[3]);
quat = parentquat*quat;
float newQuat[4] = {quat.X, quat.Y, quat.Z, quat.W};
QuaternionToMatrix(newQuat,absolutePose[iter->boneID].orientation);
//////
nextParent = hierarchy->find(nextParent->boneID);
}
}
我已经有一段时间的问题了,我也尝试过保持矩阵模式并切换到Euler角度。有人能帮我找出我做错了什么吗?不管你用的是矩阵还是四元数。我建议不要在这里使用欧拉角。在我看来,问题在于,当转换为局部坐标时,您将反转子四元数而不是父四元数,而当转换为全局坐标时,您不会传播旋转 假设方向应用于右侧的列向量: q_1、q_2和q_3是链中三个物体的全局方向。如果我们想使用相对方向r_2和r_3,那么必须将父对象的旋转从其子对象中移除。我们可以看到q_2=q_1*r_2和q_3=q_1*r_2*r_3=q_2*r_3 求相对值,得到r_3=q_2'*q_3,同样,r_2=q_1'*q_2,其中q_2'是矩阵或四元数的逆 如果要从全局转换为局部,则需要记住: q_3=q_1*r_2*r_3 所有父方向都需要向下传播到最终子体。因此,您要么需要使用递归来获取从子对象到根对象的所有方向更改,要么需要从父对象开始,在向下遍历子对象时传播/累积每个链接的所有方向更改
作为事后考虑,我认为您还需要确保根节点意识到其相对位置等于其绝对位置。否则您将遇到问题。使用矩阵或四元数无关紧要。我建议不要在这里使用欧拉角。在我看来,问题在于,当转换为局部坐标时,您将反转子四元数而不是父四元数,而当转换为全局坐标时,您不会传播旋转 假设方向应用于右侧的列向量: q_1、q_2和q_3是链中三个物体的全局方向。如果我们想使用相对方向r_2和r_3,那么必须将父对象的旋转从其子对象中移除。我们可以看到q_2=q_1*r_2和q_3=q_1*r_2*r_3=q_2*r_3 求相对值,得到r_3=q_2'*q_3,同样,r_2=q_1'*q_2,其中q_2'是矩阵或四元数的逆 如果要从全局转换为局部,则需要记住: q_3=q_1*r_2*r_3 所有父方向都需要向下传播到最终子体。因此,您要么需要使用递归来获取从子对象到根对象的所有方向更改,要么需要从父对象开始,在向下遍历子对象时传播/累积每个链接的所有方向更改
作为事后考虑,我认为您还需要确保根节点意识到其相对位置等于其绝对位置。否则您将遇到问题。我有包含骨骼绝对位置的矩阵。我想把它们转换成相对位置。你的答案是什么?对不起,这是3D编程的新手。我有包含骨骼绝对位置的矩阵。我想把它们转换成相对位置。你的答案是什么?对不起,我对3D编程非常陌生。