我正在使用四元数和XNA蒙皮模型示例(几周以来……)。我从一些开源的感应板上收到了两组四元数,这些天你可以在网上买到。我能够写一些代码,这样我就可以接收这些四元数,并且能够用它们旋转四肢。现在我的问题如下。在我的例子中,我使用的是右上臂和右下臂,我可以分别旋转它们。我的初始位置如下图所示,非常完美。
http://i.imgur.com/c7qei.png“初始位置”
现在,当我想要向前旋转我的右臂时,我应该有我的最终位置,如下图右侧所示。但不知何故,结果是左侧的一个位置,但我真正的“身体”手臂指向前方。
http://i.imgur.com/tXCp6.png“理想最终位置(右),实际错误位置(左)”
有些人认为下臂不能补偿上臂的旋转。我确信我遗漏了一小步。下面我把我正在使用的代码的关键部分放在下面
protected override void Update(GameTime gameTime)
{
HandleInput();
UpdateCamera(gameTime);
// Read gamepad inputs.
float initposition = currentGamePadState.ThumbSticks.Right.X;
float armRotation = Math.Max(currentGamePadState.ThumbSticks.Right.Y, 0);
// these quaternions are received from bluetooth
Upper.Z = Fq1;
Upper.Y = -Fq2;
Upper.X = -Fq3; // set 1 quaternions
Upper.W = Fq4;
//***************************
forearm.Z = Uq1;
forearm.Y = -Uq2;
forearm.X = -Uq3;
forearm.W = Uq4; // set 2 quaternions
// set initial position
if (initialpos == true)
{
initposition = 0.9f;
R_forTransform = Matrix.CreateRotationY(initposition);
R_forarminderinit = skinningData.BoneIndices["R_UpperArm"];
L_forTransform = Matrix.CreateRotationY(-initposition);
L_forTransform = Matrix.CreateRotationX(-initposition);
L_forTransform = Matrix.CreateRotationZ(-initposition);
L_forarminderinit = skinningData.BoneIndices["L_UpperArm"];
}
// Create rotation matrices for the upper and lower arm bones.
Matrix upperarmTransform = Matrix.CreateFromQuaternion(Upper);
Matrix forearmTransform = Matrix.CreateFromQuaternion(forearm);
animationPlayer.GetBoneTransforms().CopyTo(boneTransforms, 0);
if (initialpos == true)
{
boneTransforms[R_forarminderinit] = R_forTransform * boneTransforms[R_forarminderinit];
boneTransforms[L_forarminderinit] = L_forTransform * boneTransforms[L_forarminderinit];
}
int forearmindex = skinningData.BoneIndices["R_Forearm"];
int upperarmindex = skinningData.BoneIndices["R_UpperArm"];
boneTransforms[upperarmindex] = upperarmTransform * boneTransforms[upperarmindex];
boneTransforms[forearmindex] = (forearmTransform) * boneTransforms[forearmindex];
animationPlayer.UpdateWorldTransforms(Matrix.Identity, boneTransforms);
animationPlayer.UpdateSkinTransforms();
UpdateBoundingSpheres();
base.Update(gameTime);
}我想问你是否能帮我解开这个谜团。我希望我已经尽可能清楚地描述了我的问题。此外,我要提前感谢您所做的努力。
你的
戴夫
发布于 2012-12-05 23:45:11
在我看来,你有一些混淆的参照系。这是我认为我看到的:
你的外部传感器会报告它们相对于世界的方向。另一方面,渲染代码处理上臂参考帧中的下臂。
如果我们假设初始方向为q_u = 0,0,0,1和q_l=0,0,0,1,则当旋转手臂以指向前方时,新方向都是0、.707,0、.707或类似的方向,因为两个手臂分段都经历了/2π相对于世界的旋转。
渲染手臂时,可以通过q_u旋转整个手臂(而不仅仅是上臂)。这是有意义的,因为您希望确保肘部保持连接。但是,当您使用q_l旋转小臂时,因为它保持了肩膀的旋转,所以它已经旋转了两倍。如果你保持手臂伸直,但身体转过来,你会看到同样的事情发生:上臂会随着身体旋转的量而旋转,而下臂又会旋转同样的量。
也许处理此问题的最简单方法是将q_u从q_l中删除。如果q_k是小臂相对于上臂的旋转,则q_k = q_u' * q_l,其中q_u'是反四元数(只需对w分量求反)。
https://stackoverflow.com/questions/13707249
复制相似问题