C# WPF AxisAngleRotation3D与XNA CreateFromAxisAngle

C# WPF AxisAngleRotation3D与XNA CreateFromAxisAngle,c#,wpf,xna,C#,Wpf,Xna,我对3D很笨,就像我的问题可能是: 我在WPF中制作了一个“查看器”程序,可以在屏幕上呈现内容,也可以旋转内容。我用它来旋转适合我口味的东西: 代码:WPF Transform3DGroup tg = new Transform3DGroup(); tg.Children.Add(new ScaleTransform3D(sx, sy, 1)); tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(

我对3D很笨,就像我的问题可能是:

我在WPF中制作了一个“查看器”程序,可以在屏幕上呈现内容,也可以旋转内容。我用它来旋转适合我口味的东西:

代码: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);
我决定在XNA中制作这个程序,因为它似乎要快一点,但是我无法使它工作

以这种方式尝试(代码,XNA):

我甚至尝试了CreateFromYawPitchRoll,也尝试了CreateRotationX(YZ),但没有运气,屏幕上绘制的东西总是以不同的方式旋转。所以我猜我会问这里的大脑,他们是否知道我要在这两种技术之间做什么计算

提前谢谢

编辑:我在其他论坛上尝试过,在那里我被要求了解详细信息。我也在这里复制/粘贴它们 XNA代码如下所示:

主要

区域对象

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();
  }
}
constructor:将效果和设备设置为与main相同,将Pozició(包含当前位置和旋转的矩阵)设置为origo
...
公共虚拟Alapmodel Inicializálás(浮点x、浮点y、浮点z、浮点rx、浮点ry、浮点rz、浮点sx、浮点sy)
{
//当坐标来自文件且未使用Pozició=矩阵设置时,此初始值设定项启动,因此我们要转换。此初始值设定项仅运行一次。覆盖设置顶点位置和纹理
VertexDeclaration=新的VertexDeclaration(设备,VertexositionTexture.VertexElements);
Pozició=矩阵.CreateScale(sx,sy,1f);//méretezés
Pozició*=矩阵.CreateFromAxisAngle(Vector3.UnitX,rx);//forgatás
Pozició*=矩阵.CreateFromAxisAngle(Vector3.UnitY,ry);
Pozició*=矩阵.CreateFromAxisAngle(Vector3.UnitZ,rz);
Pozició*=Matrix.CreateTranslation(x,y,z);//középpont
//我们设置了起始位置-在其他任何地方我们都不这样做,从这里只有主循环可以修改它,…可以..但不能。这是区域,只有静态对象-从不移动
}
公共无效Rajzolj()
{
//这将绘制对象(其中可以是分区或静态对象)
foreach(EffectPass-in-effect.currentTechnology.passs)
{
pass.Begin();
foreach(Elem Elem in Elemek)
{
//维吉梅吉·恩克·阿兹·埃莱梅肯
effect.Texture=elem.Textúra;
//波齐齐奥纳拉斯
effect.World=Pozició;//我们采取初始化的位置
effect.CommitChanges();//这是必需的。如果不使用此选项,纹理将被破坏
device.VertexDeclaration=VertexDeclaration;
device.DrawUserIndexedPrimitions(PrimitiveType.TriangelList,Poziciók,0,Poziciók.Length,elem.Indexek,0,elem.Indexek.Length/3);
}
pass.End();
}
}
就这样。我仍然认为这是一些转换,而不是绘图代码。其他任何地方的立场都没有改变。我猜矩阵就像WPFs堆叠变换一样——我的问题是,我不知道在两者之间转换的数学。WPF代码工作完美,区域中的模型显示良好XNA代码在某种程度上是不好的,因为Inicializálás()中的x、y、z等的转换错误。在这方面,我确实需要帮助。


提前谢谢。

我建议不要以角度的方式存储方向


但是有时候,在xna版本中,您的问题可以通过先应用Z旋转,然后是X旋转,然后是Y旋转来解决。

您也可以使用CreateWorld,但它没有缩放功能,所以我决定一步一步地解决这个问题。首先是放入origo,然后缩放,然后旋转缩放,然后缩放并旋转缩放

要使用弧度而不是度数,如果有度数,请使用MathHelper.ToRadians(),就像我所做的那样

如果你来自WPF,并且你的旋转角度在那里工作,但这里不是,在你计算弧度之前,试着用360/512乘以你的角度。你们可以在注释中看到这个例子,你们要用它来表示所有的rx,ry和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

如果你能给出更快的公式,那么*360/512,或者一些看起来更好的东西,请发表评论。

忘记添加:XNA 3.1-但我想在这种情况下,它不是一个大问题,但对我来说不起作用。我不认为这是旋转的顺序,因为当我尝试CreateFromYawPitchRoll时,所有的旋转都是同时进行的,这也不起作用。这就是为什么我想这是一些数学,可能是XNA中的输入和WPF中的输入之间的一些转换。我想说服您,如果您不考虑rx、ry和rz,而是将方向存储在矩阵或四元数中,您的问题/解决方案将大大简化。但我不认为这个评论部分的角色限制会允许这样做,而且这不是对你问题的直接回答,所以我不会。如果你最终陷入困境,请考虑交替方向表示。XNA代码示例中的“PoZiCi”是矩阵类型,我只是为了从其他源(从文件)转换坐标和旋转(和缩放)。
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();
  }
}
        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