Вращение кубов в XNA

До сих пор мне удалось создать 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);, но даже тогда я не уверен, куда его поместить и использовать.

Любые идеи? Любая помощь будет высоко ценится.


person DAVETELFA    schedule 11.08.2010    source источник
comment
Хотелось бы, чтобы у меня было достаточно представителей, чтобы отредактировать ваш пост и исправить форматирование вашего кода...   -  person Andrew Russell    schedule 12.08.2010
comment
Вау, спасибо за такой совершенно бессмысленный пост. Если вам нечего сказать по моему фактическому вопросу и запросу, зачем писать в ветке? Если вы не можете предложить помощь, кроме как прокомментировать формат кода — что совершенно очевидно, потому что я скопировал его из файла — пожалуйста, потроллите какую-нибудь другую тему. Спасибо. ДэйвТ   -  person DAVETELFA    schedule 12.08.2010
comment
Мой комментарий о вашем форматировании не предназначался для личного восприятия. Но если это то, как вы хотите играть: если вы слишком ленивы или некомпетентны, чтобы приложить усилия, чтобы сделать ваш пост читабельным, ДАЖЕ после того, как вам на него укажут (помощь по форматированию нетрудно найти!), И вы оскорбляете кого-то, кто (дважды сейчас) нашел время, чтобы посетить ваш вопрос с целью ответить на него, И оказалось, что ваш вопрос был просто скопирован откуда-то из середина ветки, которую вы создали на форуме XNA, то я не вижу причин, по которым КТО-ТО должен прилагать какие-либо усилия, чтобы помочь вам.   -  person Andrew Russell    schedule 12.08.2010
comment
Ничего себе, тогда давайте снова накормим тролля.. Так вы говорите мне, что мой исходный пост полностью неразборчив из-за плохого форматирования кода? Хорошо, тогда. Оскорбительный? Нет. Я просто указал на тот факт, что если вы только критикуете форматирование моего кода, а не помогаете с моим вопросом, пожалуйста, не публикуйте. Это слишком сложный запрос? Если бы вы действительно критиковали мой код, то у меня не было бы с этим проблем. О, и молодец, Шерлок, я тоже разместил это на форуме xna.. Твоя точка зрения? Получить несколько мнений о том, как что-то сделать, лучше, чем одно. Спасибо. ДэйвТ   -  person DAVETELFA    schedule 12.08.2010


Ответы (2)


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

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

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

Итак, допустим, у вас есть класс 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);
   }
}

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

person Steve H    schedule 21.08.2010

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

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

person Dominiek    schedule 13.08.2010