在XNA中旋转立方体

时间:2010-08-11 11:57:26

标签: 3d xna rotation rubiks-cube

到目前为止,我已设法为轮换创建Quaternion。现在唯一的问题是,如何将其应用于某些立方体?当我按下键盘上的右键时,每个立方体都在原点周围连续旋转。

作为参考,我有8个立方体位于与魔方(2x2x2)类似的设置中。所以当我按下右/左箭头时,'立方体'的右/左面(由8个较小的立方体组成的大立方体),顺时针/逆时针旋转90度。

其中一个立方体的示例(总共八个立方体中)声明:

GameObject subCube3 = new GameObject();  
Vector3 subCube3Pos = new Vector3(-0.55f, -0.55f, 0.55f); 

在我的更新方法中:

// declare rotation floats     
float updownRotation = 0.0f;     
float leftrightRot = 0.0f;     

// get state of keyboard     
KeyboardState keys = Keyboard.GetState();     

// if key is pressed, change value of rotation     
if (keys.IsKeyDown(Keys.Right))     
{     
    leftrightRot = -0.10f;     
}

// if key is pressed, change value of rotation     
if (keys.IsKeyDown(Keys.Left))     
{     
    leftrightRot = 0.1f;     
}     

// if key is pressed, change value of rotation     
if (keys.IsKeyDown(Keys.Up))     
{
    updownRotation = 0.1f;     
}

// rotation around axis     
Quaternion addRot = Quaternion.CreateFromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), leftrightRot);

//rotation of cubes     
cubeRotation = cubeRotation * addRot; 

我的绘画功能:

void DrawGameObject(GameObject gameobject)
{     
    //graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;     
    foreach (ModelMesh mesh in gameobject.model.Meshes)     
    {     
        foreach (BasicEffect effect in mesh.Effects)     
        {     
            effect.EnableDefaultLighting();     
            effect.PreferPerPixelLighting = true;     
            effect.World =     
                Matrix.CreateScale(gameobject.scale) *     
                Matrix.CreateFromQuaternion(cubeRotation) *     
                Matrix.CreateTranslation(gameobject.position);     

            effect.Projection = cameraProjectionMatrix;     
            effect.View = cameraViewMatrix;     
        }
        mesh.Draw();     
    }
}

我认为问题是Matrix.CreateTranslation(gameobject.position)显然会影响我的所有立方体。我已经尝试创建新的Vector3,即c_component1 = Vector3.Transform(cube1pos, cubeRotation);,但即便如此,我也不确定在哪里放置它并实际使用它。

任何想法?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

对于rubix多维数据集方案,除了已有的quat之外,还需要每个较小的多维数据集的四元数。这些较小的quats表示它们与整个批次(您当前拥有的那个)的quat之间的方向差异。认为这里的层次结构与骨骼系统不同。当你只想旋转几个立方体(比如左边的所有立方体)时,你只能将旋转四元组乘以那些特定的较小立方体的quats,其他的不旋转。

然后,为了绘图,您可以通过将小立方体的quat与大立方体的quat连接来创建最终的方向quat。为每个小立方体做到这一点。

对于表示所有较小立方体位置的vector3,您将需要相同的结构。

所以,假设你有一个名为SmallCube的类并且已经实例化了8次。它有一个quat和一个Vector3(用于位置)。

假设立方体布置在世界起源和周围。你只想旋转上面的那些。

Foreach(smallCube sc in smallCubes)
{
   if(sc.Position.Y > 0.1f)
   {
     Quaternion addRot = Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.ToRadians(90));
     sc.quat *= addRot
     sc.Position = Vector3.Transform(sc.Position, addRot);
   }
}

使用Quaternions而不是Matrices还有一个额外的好处。您可以使用内置的Quaternion.Dot()方法来测试求解。如果所有小立方体方向相同,则必须排列所有颜色。发生这种情况时,所有点积都是1.0f。矩阵中没有平等的能力。

答案 1 :(得分:0)

你需要一些技巧来选择你想要旋转的特定立方体,比如通过点击它(在初学者的XNA中很难)或者通过按键盘上的某个数字,然后在每个GameObject中,你可以检查它是否可以已选中,仅在应用旋转时才会应用。

希望这是有道理的......