C# 三维网格旋转

C# 三维网格旋转,c#,3d,xna,C#,3d,Xna,我对3D图形还比较陌生,我发现了很多关于旋转的例子,但是我相信我的代码在创建3D网格或旋转本身方面出了问题。我正在使用一个修改版本的 所以本质上我的问题归结为,我绕着红色的x线旋转,而不是蓝色的x线。理想情况下,我想在蓝色Y线和蓝色X线相交的地方旋转。也可以查看旋转函数,请参见下面列出的microsoft类几何函数,并查看RotateX 谢谢你的帮助 下面是我如何设置场景的: public RenderScene3D(short _depth, GraphicsDevice GD) : bas

我对3D图形还比较陌生,我发现了很多关于旋转的例子,但是我相信我的代码在创建3D网格或旋转本身方面出了问题。我正在使用一个修改版本的

所以本质上我的问题归结为,我绕着红色的x线旋转,而不是蓝色的x线。理想情况下,我想在蓝色Y线和蓝色X线相交的地方旋转。也可以查看旋转函数,请参见下面列出的microsoft类几何函数,并查看RotateX

谢谢你的帮助

下面是我如何设置场景的:

public RenderScene3D(short _depth, GraphicsDevice GD) : base(_depth)
{
    PrimativeCollection = new List<GeometricPrimitive>();
    cameraPosition = new Vector3(0, 0, 2.5f);
    fAspect = GD.Viewport.AspectRatio;

    CameraWorld = Matrix.CreateTranslation(cameraPosition);
    world = Matrix.CreateFromYawPitchRoll(0, 0, 0);
    view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
    projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, fAspect, .01f, 500f);
    // This serves as a base line for latter ray cursor calculations.
    ScreenProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, fAspect, .01f, 2.5f);
    graphicsDevice = GD;          
}
public RenderScene3D(短深度,图形设备GD):基础(_深度)
{
PrimativeCollection=新列表();
摄像机位置=新矢量3(0,0,2.5f);
fAspect=GD.Viewport.AspectRatio;
CameraWorld=矩阵.CreateTranslation(cameraPosition);
world=Matrix.CreateFromYawPitchRoll(0,0,0);
视图=矩阵.CreateLookAt(摄像机位置,向量3.0,向量3.Up);
投影=矩阵.CreatePerspectiveFieldOfView(MathHelper.PiOver4,fAspect.01f,500f);
//这将作为后期光线光标计算的基线。
ScreenProjection=Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,fAspect.01f,2.5f);
图形设备=GD;
}
Microsoft class Geometric的稍微修改版本:

public abstract class GeometricPrimitive : IDisposable
{
    #region Fields

    // During the process of constructing a primitive model, vertex
    // and index data is stored on the CPU in these managed lists.
    protected List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();
    protected List<ushort> indices = new List<ushort>();
    public Vector3 v3Position;
    protected Matrix world;
    protected Matrix worldPosition;
    protected Matrix worldRotation;

    // Once all the geometry has been specified, the InitializePrimitive
    // method copies the vertex and index data into these buffers, which
    // store it on the GPU ready for efficient rendering.
    protected VertexBuffer vertexBuffer;
    protected IndexBuffer indexBuffer;
    protected BasicEffect basicEffect;

    #endregion

    #region Initialization


    /// <summary>
    /// Adds a new vertex to the primitive model. This should only be called
    /// during the initialization process, before InitializePrimitive.
    /// </summary>
    protected void AddVertex(Vector3 _position, Vector3 normal)
    {
        vertices.Add(new VertexPositionNormal(_position, _position));
    }


    /// <summary>
    /// Adds a new index to the primitive model. This should only be called
    /// during the initialization process, before InitializePrimitive.
    /// </summary>
    protected void AddIndex(int index)
    {
        if (index > ushort.MaxValue)
            throw new ArgumentOutOfRangeException("index");

        indices.Add((ushort)index);
    }


    /// <summary>
    /// Queries the index of the current vertex. This starts at
    /// zero, and increments every time AddVertex is called.
    /// </summary>
    protected int CurrentVertex
    {
        get { return vertices.Count; }
    }


    /// <summary>
    /// Once all the geometry has been specified by calling AddVertex and AddIndex,
    /// this method copies the vertex and index data into GPU format buffers, ready
    /// for efficient rendering.
    public void InitializePrimitive(GraphicsDevice graphicsDevice)
    {
        // Create a vertex declaration, describing the format of our vertex data.

        // Create a vertex buffer, and copy our vertex data into it.
        vertexBuffer = new VertexBuffer(graphicsDevice,
                                        typeof(VertexPositionNormal),
                                        vertices.Count, BufferUsage.None);

        vertexBuffer.SetData(vertices.ToArray());

        // Create an index buffer, and copy our index data into it.
        indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
                                      indices.Count, BufferUsage.None);

        indexBuffer.SetData(indices.ToArray());

        // Create a BasicEffect, which will be used to render the primitive.
        basicEffect = new BasicEffect(graphicsDevice);

        basicEffect.EnableDefaultLighting();
        RotateX(0);
        UpdateWorld();
    }

    public void Move(Vector3 Position)
    {
        v3Position = Position;
        worldPosition = Matrix.CreateTranslation(v3Position);
    }

    public void UpdateWorld()
    {
        world = worldRotation * worldPosition;
    }

    public void RotateX(float X)
    {
        Matrix rotation = worldPosition;

        Matrix.CreateRotationX(X, out rotation);
        worldRotation = rotation;
    }


    /// <summary>
    /// Finalizer.
    /// </summary>
    ~GeometricPrimitive()
    {
        Dispose(false);
    }


    /// <summary>
    /// Frees resources used by this object.
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }


    /// <summary>
    /// Frees resources used by this object.
    /// </summary>
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (vertexBuffer != null)
                vertexBuffer.Dispose();

            if (indexBuffer != null)
                indexBuffer.Dispose();

            if (basicEffect != null)
                basicEffect.Dispose();
        }
    }


    #endregion

    #region Draw


    /// <summary>
    /// Draws the primitive model, using the specified effect. Unlike the other
    /// Draw overload where you just specify the world/view/projection matrices
    /// and color, this method does not set any renderstates, so you must make
    /// sure all states are set to sensible values before you call it.
    /// </summary>
    public void Draw(Effect effect)
    {
        GraphicsDevice graphicsDevice = effect.GraphicsDevice;

        // Set our vertex declaration, vertex buffer, and index buffer.
        graphicsDevice.SetVertexBuffer(vertexBuffer);

        graphicsDevice.Indices = indexBuffer;            


        foreach (EffectPass effectPass in effect.CurrentTechnique.Passes)
        {
            effectPass.Apply();

            int primitiveCount = indices.Count / 3;

            graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Count, 0, primitiveCount);

        }
    }


    /// <summary>
    /// Draws the primitive model, using a BasicEffect shader with default
    /// lighting. Unlike the other Draw overload where you specify a custom
    /// effect, this method sets important renderstates to sensible values
    /// for 3D model rendering, so you do not need to set these states before
    /// you call it.
    /// </summary>
    public void Draw(Matrix view, Matrix projection, Color color)
    {
        // Set BasicEffect parameters.
        basicEffect.World = world;
        //Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(xwingRotation) * Matrix.CreateTranslation(xwingPosition);
        //Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(xwingRotation) * Matrix.CreateTranslation(xwingPosition);
        //Matrix test = view.Translation * new Vector3(0,0,0.001f);
        basicEffect.View = view;
        basicEffect.Projection = projection;
        basicEffect.DiffuseColor = color.ToVector3();
        basicEffect.Alpha = 128.0f / color.A;

        GraphicsDevice device = basicEffect.GraphicsDevice;
        // Reset the fill mode renderstate.
        device.DepthStencilState = DepthStencilState.Default;

        if (color.A < 255)
        {
            // Set renderstates for alpha blended rendering.
            device.BlendState = BlendState.AlphaBlend;
        }
        else
        {
            // Set renderstates for opaque rendering.
            device.BlendState = BlendState.AlphaBlend;
        }

        // Draw the model, using BasicEffect.
        Draw(basicEffect);
    }
}
公共抽象类GeometricPrimitive:IDisposable
{
#区域字段
//在构造基本模型的过程中,顶点
//索引数据存储在这些托管列表中的CPU上。
受保护的列表顶点=新列表();
受保护列表索引=新列表();
公共向量3 v3位置;
保护矩阵世界;
保护矩阵位置;
保护矩阵旋转;
//一旦指定了所有几何图形,则初始值Primitive
//方法将顶点和索引数据复制到这些缓冲区中
//将其存储在GPU上,以便高效渲染。
受保护的顶点缓冲区顶点缓冲区;
受保护的索引缓冲索引缓冲;
受保护的基本效果基本效果;
#端区
#区域初始化
/// 
///将新顶点添加到基本体模型中。应仅调用该顶点
///在初始化过程中,在初始化之前Primitive。
/// 
受保护的void AddVertex(向量3_位置,向量3法线)
{
添加(新顶点曝光法线(_位置,_位置));
}
/// 
///向基元模型添加新索引。只应调用此索引
///在初始化过程中,在初始化之前Primitive。
/// 
受保护的void AddIndex(整数索引)
{
如果(索引>ushort.MaxValue)
抛出新ArgumentOutOfRangeException(“索引”);
索引。添加((ushort)索引);
}
/// 
///查询当前顶点的索引。此操作从开始
///零,并在每次调用AddVertex时递增。
/// 
受保护的int-CurrentVertex
{
获取{返回顶点数;}
}
/// 
///调用AddVertex和AddIndex指定所有几何体后,
///此方法将顶点和索引数据复制到GPU格式缓冲区中,准备就绪
///用于高效渲染。
public void InitializePrimitive(图形设备图形设备)
{
//创建顶点声明,描述顶点数据的格式。
//创建顶点缓冲区,并将顶点数据复制到其中。
vertexBuffer=新的vertexBuffer(图形设备,
类型(垂直曝光正常),
顶点。计数,缓冲区使用率。无);
SetData(顶点.ToArray());
//创建一个索引缓冲区,并将索引数据复制到其中。
indexBuffer=新的indexBuffer(图形设备,类型(ushort),
索引。计数,缓冲区使用率。无);
SetData(index.ToArray());
//创建一个BasicFect,用于渲染基本体。
BasicFect=新的BasicFect(图形设备);
basicEffect.EnableDefaultLighting();
RotateX(0);
UpdateWorld();
}
公共无效移动(矢量3位置)
{
V3位置=位置;
worldPosition=Matrix.CreateTranslation(v3Position);
}
public void UpdateWorld()
{
世界=世界旋转*世界位置;
}
公共空间旋转(浮动X)
{
矩阵旋转=世界位置;
矩阵.CreateRotationX(X,向外旋转);
世界旋转=旋转;
}
/// 
///终结器。
/// 
~GeometricPrimitive()
{
处置(虚假);
}
/// 
///释放此对象使用的资源。
/// 
公共空间处置()
{
处置(真实);
总干事(本);
}
/// 
///释放此对象使用的资源。
/// 
受保护的虚拟void Dispose(bool disposing)
{
如果(处置)
{
if(vertexBuffer!=null)
vertexBuffer.Dispose();
if(indexBuffer!=null)
indexBuffer.Dispose();
if(basicEffect!=null)
基本效果处理();
}
}
#端区
#区域绘制
/// 
///使用指定的效果绘制基本体模型。与其他
///在仅指定世界/视图/投影矩阵的位置绘制重载
///和颜色,此方法不设置任何渲染状态,因此必须
///在调用之前,请确保所有状态都设置为合理值。
/// 
公共无效提取(效果)
{
GraphicsDevice GraphicsDevice=effect.GraphicsDevice;
//设置顶点声明、顶点缓冲区和索引缓冲区。
graphicsDevice.SetVertexBuffer(vertexBuffer);
graphicsDevice.Index=indexBuffer;
foreach(效应传递效应传入
public class SquarePrimitive : GeometricPrimitive
{
    public float size;
    /// <summary>
    /// Constructs a new square primitive, using default settings.
    /// </summary>
    public SquarePrimitive(Vector3 position, Vector3 _v3Rotation)
        : this(position, _v3Rotation, 1)
    {

    }

    /// <summary>
    /// Constructs a new square primitive, with the specified size.
    /// </summary>
    public SquarePrimitive(Vector3 position, Vector3 _v3Rotation, float _size)
    {
        size = _size;
        // Get two vectors perpendicular to the face normal and to each other.
        Vector3 topLeft = new Vector3(-size, size, 0);
        Vector3 topRight = new Vector3(size, size, 0);
        Vector3 bottomLeft = new Vector3(-size, -size, 0);
        Vector3 bottomRight = new Vector3(size, -size, 0);

        // Six indices (two triangles) per face.
        AddIndex(CurrentVertex + 0);
        AddIndex(CurrentVertex + 1);
        AddIndex(CurrentVertex + 2);

        AddIndex(CurrentVertex + 0);
        AddIndex(CurrentVertex + 2);
        AddIndex(CurrentVertex + 3);

        // Four vertices per face.
        size = 0.1f;
        AddVertex((position + topLeft), position);
        AddVertex((position + topRight), position);
        AddVertex((position + bottomRight), position);
        AddVertex((position + bottomLeft), position);

        Move(position);
    }
}
    AddVertex((position + topLeft), position);
    AddVertex((position + topRight), position);
    AddVertex((position + bottomRight), position);
    AddVertex((position + bottomLeft), position);