Вращающиеся кубики в XNA - PullRequest
       27

Вращающиеся кубики в XNA

3 голосов
/ 11 августа 2010

Пока мне удалось создать 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 ]

1 голос
/ 22 августа 2010

Для сценария с кубиком рубикса, в дополнение к уже имеющемуся квату, вам потребуется кватернион для каждого меньшего куба. эти меньшие кваты представляют разницу ориентации между ними и кватом для всего пакета (тот, который у вас есть в настоящее время). Подумайте, иерархическая структура здесь ничем не отличается от костной системы. Если вы хотите повернуть только несколько кубов (скажем, все с левой стороны), вы должны только умножить кват вращения на квоты этих конкретных меньших кубов, остальные не вращаются.

Затем для рисования вы создаете окончательный ориентационный кват, конкатенируя кват маленького куба с кватом большого куба. Сделайте это для каждого маленького кубика.

Вам понадобится та же структура для векторов, представляющих позиции всех меньших кубов.

Итак, допустим, у вас есть класс SmallCube, и он был создан 8 раз. Он содержит кват и 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);
   }
}

Использование кватернионов для этого в отличие от матриц имеет дополнительное преимущество. Вы можете использовать встроенный метод Quaternion.Dot () для проверки решения. Если все маленькие ориентации куба одинаковы, все цвета должны быть выровнены. Когда это произойдет, все скалярное произведение будет 1.0f. В матрицах нет равных возможностей.

0 голосов
/ 13 августа 2010

Вам понадобится какой-то метод, чтобы выбрать конкретный куб, который вы хотите повернуть, например, щелкнув по нему (довольно сложно в XNA для новичка) или нажав какое-то число на клавиатуре, затем в каждом GameObject вы можете проверить, если он выбран и применяется только вращение, если оно есть.

Надеюсь, это имеет смысл ...

...