2010-12-03 3 views
2

Je suis assez stupide à la 3D, tout comme ma question peut être:WPF AxisAngleRotation3D contre XNA CreateFromAxisAngle

J'ai fait un programme de « spectateur » dans WPF qui rend des choses à l'écran, et ce qui peut être mis en rotation ainsi. J'utilise ce pour la rotation ce qui fonctionne pour mon goût:

code: WPF

Transform3DGroup tg = new Transform3DGroup(); 
tg.Children.Add(new ScaleTransform3D(sx, sy, 1)); 
tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), rx))); 
tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), ry))); 
tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), rz))); 
tg.Children.Add(new TranslateTransform3D(x, y, z)); 
darabka.Transform = tg; 
TeljesModell.Children.Add(darabka); 

j'ai décidé de faire de ce programme XNA, parce que cela semble être un peu plus rapide, mais je ne pouvais pas le faire à travail.

Essayé de cette façon (Code, XNA):

Pozició = Matrix.CreateScale(sx, sy, 1f);       //méretezés 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitX, rx);   //forgatás 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitY, ry); 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitZ, rz); 
Pozició *= Matrix.CreateTranslation(x, y, z);      //középpont 

J'ai essayé même CreateFromYawPitchRoll, CreateRotationX (YZ) aussi, mais sans chance, les choses drawed à l'écran a toujours été tourné différemment. Donc je devine que je demande aux cerveaux ici s'ils savent quelles maths je dois mettre entre les deux technologies.

Merci d'avance.

éditer: J'ai essayé sur d'autres forums où on m'a demandé des détails. Copier/coller ici aussi Le code est comme XNA:

principale

... 
protected override void LoadContent() 
{ 
t3 = new Airplane(); //this is a "zone" object, having zone regions and zone objects in it. all of them together give the zone itself as a static object, where player walks in 
Kamera.Példány.Pozició = new Vector3(1362, 627, -757); //starting pozition in the zone - this is camera position so the player's starting pozition. (camera is FPS) 
... 
} 
... 
protected override void Update(GameTime gameTime) 
{ 
... 
Kameramozgatása();                //kamera mozgatását vezérlő billentyűk 
//this moves the FPS camera around 
} 
... 
protected override void Draw(GameTime gameTime) 
{ 
... 
ÁltalánosGrafikaiObjektumok.Effect.View = Kamera.Példány.Idenézünk;     //camera views this 
ÁltalánosGrafikaiObjektumok.Effect.Projection = projectionMatrix;     //... and camera views FROM is set in Kameramozgatása() 
... 
t3.Rajzolj(); //draw zone object 
... 
} 
objet zone

constructor: set the effect and device to the same as main, set the Pozició (a matrix containing the current position and rotations) to origo 
... 
public virtual Alapmodel Inicializálás(float x, float y, float z, float rx, float ry, float rz, float sx, float sy) 
{ 
//this initializer starts when the coordinates are from a file and not set with Pozició = Matrix....., so we are to convert. this runs only one time. overrides set the vertex positions and textures 
VertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements); 
Pozició = Matrix.CreateScale(sx, sy, 1f);    //méretezés 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitX, rx);  //forgatás 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitY, ry); 
Pozició *= Matrix.CreateFromAxisAngle(Vector3.UnitZ, rz); 
Pozició *= Matrix.CreateTranslation(x, y, z);   //középpont 
//we set the starting position - nowhere else we do it, from here only the main loop can modify this,... could.. but does not. this is zone, and has only static objects - never moving 
} 
public void Rajzolj() 
{ 
//this draws the object (what can be a zone or a static object in it) 
foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
{ 
    pass.Begin(); 
    foreach (Elem elem in Elemek) 
    { 
    //végigmegyünk az elemeken   
    effect.Texture = elem.Textúra; 

    //pozicionálás 
    effect.World = Pozició; //we take the initialized position 

    effect.CommitChanges(); //this is needed. if you do not use this, the textures will be screwed up 
    device.VertexDeclaration = VertexDeclaration; 
    device.DrawUserIndexedPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, Poziciók, 0, Poziciók.Length, elem.Indexek, 0, elem.Indexek.Length/3); 
    } 
    pass.End(); 
    } 
} 

Voilà. Je suppose encore que c'est une conversion et non un code de dessin. Nulle part ailleurs, la position n'est modifiée. J'ai deviné que les matrices sont comme les transformations empilées WPF - mon problème était et est que je ne connais pas les maths à convertir entre les deux. Le code WPF fonctionne parfaitement, les modèles de la zone se montrent bons. Le code XNA est mauvais en quelque sorte, parce que Inicializálás() a une mauvaise conversion de x, y, z, etc. dedans. En cela j'ai besoin d'aide.

Merci d'avance.

+0

oublié d'ajouter: XNA 3.1 - mais je suppose que dans ce cas, ce n'est pas un biggy –

Répondre

1

Vous pouvez également utiliser CreateWorld, mais il n'y a pas de mise à l'échelle, alors j'ai décidé de résoudre ce problème étape par étape. La première consiste à mettre à l'origo, puis à mettre à l'échelle, puis à faire tourner l'échelle, puis à le mettre à l'échelle et à le faire pivoter.

Vous devez utiliser radian, au lieu de degré, si vous avez un degré, utilisez le MathHelper.ToRadians(), comme je l'ai fait.

Si vous venez de WPF et que vos angles de rotation y travaillent, mais pas ici, essayez de multiplier votre angle avec 360/512 avant de le calculer en radians. Vous voyez un exemple pour cela dans le commentaire, vous devez l'utiliser pour tout rx, ry et rz.

 Pozició = Matrix.CreateTranslation(Vector3.Zero);      //alappozíció az origó 
     if (sx != 1 || sy != 1) Pozició *= Matrix.CreateScale(sx, sy, 1f); //méretezés 
     if (rx != 0 || ry != 0 || rz != 0) Pozició *= Matrix.CreateFromYawPitchRoll(
           MathHelper.ToRadians(rx)      //WPFből: MathHelper.ToRadians(rx * 360f/512f) 
           , MathHelper.ToRadians(ry) 
           , MathHelper.ToRadians(rz) 
          ); 
     if (x != 0 || y != 0 || z != 0) Pozició *= Matrix.CreateTranslation(x, y, z);       //középpont 

Si vous pouvez donner une formule plus rapide que * 360/512, ou quelque chose qui a l'air mieux, s'il vous plaît commenter.

1

Je vous déconseille de stocker votre orientation de façon angulaire de cette façon ...

mais il y a des moments où votre problème peut être résolu dans la version XNA simplement en appliquant la rotation Z d'abord, puis X, puis Y

+0

Essayé, mais n'a pas fonctionné pour moi. Je ne pense pas que ce soit l'ordre des rotations, parce que quand j'essaye CreateFromYawPitchRoll c'est toutes les rotations à la fois, et cela n'a pas fonctionné aussi. C'est pourquoi je suppose que c'est un calcul, une conversion peut-être entre l'entrée dans XNA et l'entrée dans WPF. –

+0

Je voudrais vous convaincre que votre problème/solution serait grandement simplifié si vous vous dérangez de rx, ry et rz, et stockez l'orientation dans une matrice ou un quaternion à la place. mais je ne pense pas que la limite de caractères dans cette section de commentaire le permettra et ce n'est pas une réponse directe à votre question, donc je ne le ferai pas. Si vous finissez par rester bloqué, envisagez d'autres représentations d'orientation. –

+0

Le "pozició" dans l'exemple de code XNA est le type de matrice, je suis juste pour convertir les coordonnées et les rotations (et la mise à l'échelle) d'une autre source (à partir d'un fichier). –