tags:

views:

122

answers:

2

Right, so far I have managed to create a Quaternion for rotation. Only problem is now, how do I apply it to only certain cubes? As when I press the right key on the keyboard at the moment, every cube is being rotated continiously around the origin.

For reference, I have 8 cubes positioned in a similar set-up to that of a Rubik's Cube (2x2x2). So when I press the right/left arrow, the right/left face of the 'Cube' (big cube made up of the 8 smaller cubes), rotates 90 degrees clockwise/anti-clockwise.

An example of one of the Cubes (out of eight cubes in total) declaration:

view sourceprint?1 GameObject subCube3 = new GameObject();  
Vector3 subCube3Pos = new Vector3(-0.55f, -0.55f, 0.55f); 

In my update method:

// 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;     
        }     
19      
20             // if key is pressed, change value of rotation     
21             if (keys.IsKeyDown(Keys.Up))     
22             {     
23                 updownRotation = 0.1f;     
24             }     

        // rotation around axis     
29             Quaternion addRot = Quaternion.CreateFromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), leftrightRot);     
30      
31             //rotation of cubes     
32             cubeRotation = cubeRotation * addRot; 

My draw function:

 void DrawGameObject(GameObject gameobject)     

02     {     
 //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();     
      }     
  }     

}

What I think is the problem is that matrix.createtranslation(gameobject.position) is obviously affecting all my cubes. I've tried creating new vector3 i.e: c_component1 = vector3.transform(cube1pos, cubeRotation) ; but even then, I am unsure where to put that and actually use it.

Any ideas anyone? Any help will be much appreciated.

-DaveT

A: 

You would need some technique to select the specific cube you wish to rotate, like by clicking it (pretty hard in XNA for a beginner) or by pressing some number on the keypad, then in each GameObject, you could check if it is selected and only apply the rotation if it is.

Hope this makes sense...

Dominiek
A: 

For a rubix cube scenario, in addition to the quat you already have, you would need a quaternion for each smaller cube. these smaller quats represent the orientation difference between them and the quat for the entire batch (the one you currently have). Think hierarchy structure here not unlike a bone sys. When you want to rotate only a few cubes (say, all on the left side) you would only multiply a rotation quat to those specific smaller cube's quats, the others don't rotate.

Then, for drawing, you create the final orientation quat by concatenating the small cube's quat with the big cube's quat. Do that for each small cube.

You will need the same structure for vector3s representing the positions of all the smaller cubes too.

So, let's say you have a class called SmallCube and have instantiated it 8 times. It holds a quat and a Vector3 (for position).

Assume the cubes are laid out around the world origin & you only want to rotate the upper ones.

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);
   }
}

Using Quaternions for this as opposed to Matrices has an additional benefit. You can use the built in Quaternion.Dot() method to test for solve. If all small cube orientations are the same, all colors must be lined up. When this occurs, all dot product will be 1.0f. There is no equivelent capability in matrices.

Steve H