与XNA 4.0,我怎样才能结合2个模型来做一个?

我想为Model1(aicraft)制作animation,我想要一个Model2(一个球体)的对象在翻译和旋转中跟随它,因为它是这架飞机的一部分。

使用下面的代码(我使用一两个教程写它),当你只是在一个角度改变时,一切似乎都很好。 球体轻轻跟随飞机,但是如果同时改变多个角度,一切都会出错。

我不知道这是不是一个万向节锁的问题? 但我使用四元数? 或者,也许我还没有理解所有这些东西?

我的代码如下:

protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // Command input to airplane float yokeUpDown = 0.0f; float yokeRightLeft = 0.0f; float RollRotation = 0.01f; //make quaternion rotation matrix of airplane Quaternion additionalAircraftRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), yokeUpDown) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), yokeRightLeft) *Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), RollRotation); //increase or decrease aircraft rotation spacecraftRotation = spacecraftRotation * additionalAircraftRotation; // make vector3 sphere angle rotation sphereAngle.X = sphereAngle.X + yokeUpDown; sphereAngle.Y = sphereAngle.Y + yokeRightLeft; sphereAngle.Z = sphereAngle.Z + RollRotation; // make rotation quaternion for sphere Quaternion additionalSphereRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), sphereAngle.X) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), sphereAngle.Y) * Quaternion.CreateFromAxisAngle(new Vector3(1,0, 0), sphereAngle.Z); //relative position of the sphere to the aircraft Vector3 translationSphere = new Vector3(-distance_Aircraft_Sphere, 0,0); translationSphere = Vector3.Transform(translationSphere, additionalSphereRotation); sphereposition = aircraftposition + translationSphere; // “VectorToAdd” = direction of the airplane Vector3 rotatedAircraftVector = Vector3.Transform(vectorToAdd, spacecraftRotation); aircraftposition += moveSpeedAircraft * rotatedAircraftVector; sphereposition += moveSpeedAircraft * rotatedAircraftVector; } enter code here 

 I wonder if it's not a gimbal lock problem? But I use quaternions? 

是的,你的代码有一个万向节锁问题,因为你使用欧拉角。 关于Gimbal Locks以及如何防止它们,有很多的神话。 如果你像你一样使用四元数,你也可以使用四元数锁。 关键不在于分别存储围绕每个轴的旋转而不是一个接一个地应用,您的代码在这里执行:

  Quaternion additionalAircraftRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), yokeUpDown) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), yokeRightLeft) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), RollRotation); Quaternion additionalSphereRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), sphereAngle.X) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), sphereAngle.Y) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), sphereAngle.Z); 

解决方法是不使用欧拉角。 {yokeUpDown, yokeRightLeft, RollRotation}sphereAngle是欧拉角。 相反,将它们存储为matrix或四元数,除了欧拉角以外,基本上任何方位/旋转的表示都可以。

此外,这段代码没有做你想做的事情,你不能只添加欧拉角来结合2轮:

  // make vector3 sphere angle rotation sphereAngle.X = sphereAngle.X + yokeUpDown; sphereAngle.Y = sphereAngle.Y + yokeRightLeft; sphereAngle.Z = sphereAngle.Z + RollRotation;