Въртящи се кубчета в XNA

Досега успях да създам Quaternion за ротация. Единственият проблем сега е как да го приложа само към определени кубчета? Както когато натисна десния клавиш на клавиатурата в момента, всяко кубче се върти непрекъснато около началото.

За справка имам 8 кубчета, разположени в настройка, подобна на тази на кубчето на Рубик (2x2x2). Така че, когато натисна стрелката надясно/наляво, дясната/лявата страна на „Куба“ (голям куб, съставен от 8 по-малки кубчета), се завърта на 90 градуса по часовниковата стрелка/обратно на часовниковата стрелка.

Пример за една от декларациите на Cubes (от общо осем куба):

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)


За сценарий с rubix куб, в допълнение към кватерниона, който вече имате, ще ви трябва кватернион за всеки по-малък куб. тези по-малки quats представляват разликата в ориентацията между тях и 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 за начинаещ) или като натиснете някакъв номер на клавиатурата, след което във всеки GameObject можете да проверите дали е избран и прилагайте въртенето само ако е така.

Дано това има смисъл...

person Dominiek    schedule 13.08.2010