我正在使用四元数和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);
}
我想问你是否可以帮助我解开这个谜团。我希望我在描述我的问题时尽可能清楚。此外,我想提前感谢您的努力。
此致
戴夫
答案 0 :(得分:0)
在我看来,你有一些混合参考框架。这就是我认为我所看到的:
您的外部传感器报告其相对于世界的方向。另一方面,渲染代码处理上臂参考系中的下臂。
如果我们假设初始方向为 q_u = [0,0,0,1] 且 q_l = [0,0,0,1] ,则你旋转你的手指向前,新的方向都是 [0,.707,0,.707] ,或类似的东西,因为两个手臂段经历了π/的旋转2 相对于世界。
渲染手臂时,通过 q_u 旋转整个手臂(不仅仅是上臂)。这是有道理的,因为你想确保肘部保持连接。但是你将下臂旋转 q_l 并且它已经旋转了两倍,因为它保持了肩膀的旋转。如果你的手臂伸直,但转动你的身体,你会看到同样的事情发生:上臂会旋转身体旋转量,下臂会旋转那么多。
处理此问题的最简单方法可能是从 q_l 中删除 q_u 。如果 q_k 是下臂相对向上臂的旋转,那么 q_k = q_u' * < strong> q_l 其中 q_u'是反四元数(只是否定w
组件)。