2012-06-11 11 views
9

Jestem nowy w XNA i tworzę prostą grę. Przepraszam, że to jest naprawdę proste, ale nie mogę znaleźć na nim żadnej pomocy. W grze jest statek, który zrobiłem z Blenderem, i chcę móc sterować statkiem poprzez możliwość obracania osi X, Y i Z statku. Oto kod, który mam:Obracanie modelu 3D w XNA

protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 
    RotationMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * Matrix.CreateRotationY (rotationY) * Matrix.CreateRotationX(rotationX) * Matrix.CreateRotationZ(rotationZ); 

     Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position); 

         DrawModel(ship.Model, shipTransformMatrix, ship.Transforms); 
     // TODO: Add your drawing code here 


     base.Draw(gameTime); 
    } 

    public void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms) 
    { 
     //Draw the model, a model can have multiple meshes, so loop 
     foreach (ModelMesh mesh in model.Meshes) 
     { 
      //This is where the mesh orientation is set 
      foreach (BasicEffect effect in mesh.Effects) 
      { 

       effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform; 
       effect.Projection = projectionMatrix; 
       effect.View = viewMatrix; 

      } 

      //Draw the mesh, will use the effects set above. 
      mesh.Draw(); 
     } 
    } 

Spowoduje to obrócenie statku, ale nie wzdłuż osi statku. Jeśli obrócę oś Y (zmieniając wartość obrotu Y), statek obróci się wzdłuż swojej osi Y. Ale jeśli obrócę oś X lub Z, statek obraca się zgodnie z osiami X i Z świata, a nie własnymi. Jak mogę to zrobić, aby statek obracał się na własnych osiach? Czy muszę robić coś innego z macierzami? Dzięki

Odpowiedz

6

Korzystanie CreateRotationX, CreateRotationY, & CreateRotationZ wszystkim stosuje rotacje na całym świecie lub globalne osie. Oznacza to, że obiekt obraca się tylko wokół osi globalnych/światowych, a nie lokalnych osi obiektu.

Za pomocą funkcji CreateFromAxisAngle można wprowadzić dowolną oś obrotu, w tym własne osie statku.

Konieczna będzie zmiana ogólnego paradygmatu rotacji, ponieważ na przykład obrót wokół dowolnej osi, na przykład statku w górę, może spowodować zmianę dowolnej z 3 wartości kąta naraz. Śledzenie wszystkiego, co jest niepotrzebnie trudne. Jest łatwiejszy sposób:

Po prostu zapisz rotację w macierzy (lub kwaternionu) zamiast 3 kątów.

+0

Dzięki. Jak zdefiniować oś obrotu mojego statku w narzędziu CreateFromAxisAngle? Próbowałem, a wszystko co robiłem, to przekształcenie mojego statku. Jak zapisać rotację w macierzy? Właśnie to próbowałem zrobić. – davidsbro

+0

Tak się składa, że ​​napisałem o tym blogu. http://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-fo--storing-an-orientation-as-3-angles/ –

+0

Dzięki. Znalazłem link, który umieściłeś tuż przed tym, jak go podniosłeś. lol. Przeczytałem to i udało mi się rozwiązać problem. Dziękuję Ci! To było naprawdę jasne i bardzo pomocne – davidsbro

2

EDIT: Giving jakiś kredyt, żeby Steve poniżej (wielki odpowiedzi kolegi, było dawno zrobiłem dużo matematyki 3D).

Ten tutorial pokazuje, jak skonfigurować sugestię Steve'a!

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/Rotation_-_translation.php

Original post:

wierzę, trzeba utworzyć effect.Rotation w swojej pętli BasicEffect.

Wszystko to jest omówione w podstawowych samouczkach w witrynie MSDN. Twój kod wygląda nawet tak, jakby był stamtąd.

http://msdn.microsoft.com/en-us/library/bb203897(v=xnagamestudio.31)

Jeśli nie, sprawdź ten link, Reimer obejmuje wszystko w 3D warto wiedzieć, aby rozpocząć:

http://www.riemers.net/eng/Tutorials/XNA/Csharp/series1.php

+0

Dzięki. Próbowałem stworzyć efekt.Rotacja w pętli BasicEffect, ale dla efektu nie było właściwości Rotation. Mój problen nie obraca modelu, mogę to zrobić, to ma modele osi obracające się z modelem. Kiedy robię 'RotationMatrix = Matrix.CreateRotationY (MathHelper.PiOver2) * Matrix.CreateRotationY (rotationY) * Matrix.CreateRotationX (rotationX) * Matrix.CreateRotationZ (rotationZ);', niezależnie od tego, która oś tworzę rotację dla pierwszego obraca się ze statkiem , ale dwa po nim nie. Czy jest tam porządek certy, muszę mieć wiele macierzy w celu ich obrócenia w/modelu? – davidsbro

+0

Porządek nie ma znaczenia (o ile kiedykolwiek zauważyłem). Ale widzę tam twój problem. Wykonaj następujące czynności: RotationMatrix = Matrix.CreateRotationY (rotationY) * Matrix.CreateRotationX (rotationX) * Matrix.CreateRotationZ (rotationZ); –

+0

Zgaduję, że MathHelper.PiOver2 miał wcześniej wyrównać twój statek pod pewnym kątem. Zamiast tego, wstępnie ustaw swój rotationY, X, Z na wartości, które mają być początkowo podczas uruchamiania. To powinno utworzyć obrót, którego szukasz. Obraca się wokół osi środkowej. –

1

Oto co skończyło się robi tylko w przypadku ktoś utknie jak ja:

Matrix RotationMatrix; 
//every time I wanted to rotate around an axis, I would do something like this: 
protected void rotateY() 
    { 
     RotationMatrix *= Matrix.CreateFromAxisAngle(RotationMatrix.Up, MathHelper.ToRadians(1.0f)); 
     //For the X axis I used RotationMatrix.Right, and for the Z RotationMatrix.Forward 
    } 
protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 


    Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position); 

        DrawModel(ship.Model, shipTransformMatrix, ship.Transforms); 
    // TODO: Add your drawing code here 


    base.Draw(gameTime); 
} 

public void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms) 
{ 
    //Draw the model, a model can have multiple meshes, so loop 
    foreach (ModelMesh mesh in model.Meshes) 
    { 
     //This is where the mesh orientation is set 
     foreach (BasicEffect effect in mesh.Effects) 
     { 

      effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform; 
      effect.Projection = projectionMatrix; 
      effect.View = viewMatrix; 

     } 

     //Draw the mesh, will use the effects set above. 
     mesh.Draw(); 
    } 
}