简体   繁体   English

在C#/ XNA中转换3D基本体的正确方法?

[英]Proper way of transforming 3D primitives in C#/XNA?

I have a Block class that basically contains an array of 36 vertices, a constructor that builds the block around the origin (0, 0, 0), and a method for updating. 我有一个Block类,该类基本上包含36个顶点的数组,一个构造器,该构造器围绕原点(0、0、0)构建块,以及一种用于更新的方法。

I'm using a Physics library to manipulate the blocks. 我正在使用物理库来操作块。 I assign a body and collision skin to the block and update the physics step every update. 我为块分配了一个身体和碰撞皮肤,并在每次更新时更新了物理步骤。 After every update I get a matrix back with the block's new position, orientation, etc. 每次更新后,我都会得到一个包含块的新位置,方向等的矩阵。

Now, what I can't wrap my head around is the best way to go about applying the matrix to the block and efficiently updating the vertex buffer every frame. 现在,我无法确定的最好方法是将矩阵应用于块并在每帧有效地更新顶点缓冲区。

This is basically what I have at the moment, I'm almost positive there's a better method... 这基本上是我目前所拥有的,我几乎肯定有更好的方法...

class Block
{
    const float FullBlockSize = 20f;
    const float HalfBlockSize = FullBlockSize / 2;

    public VertexPositionNormalTexture [] vertices = new VertexPositionNormalTexture[36];
    public VertexPositionNormalTexture [] currentVertices = new VertexPositionNormalTexture[36];
    public DynamicVertexBuffer vBuffer;

    Vector3 position;

    public Block(Vector3 blockPosition)
    {
        position = blockPosition * FullBlockSize;

        /*
         * Build the 6 faces of the block here.
         * The block is built around the origin,
         * (0, 0, 0) being the center of the block.
        */

        vBuffer = new DynamicVertexBuffer(Game.Device, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
        vBuffer.SetData(vertices);
    }
    public Matrix WorldMatrix
    {
        get
        {
            return Matrix.CreateTranslation(position);
        }
    }
    public void Update()
    {
        currentVertices = (VertexPositionNormalTexture[])vertices.Clone();
        Matrix currentWorld = WorldMatrix;
        for(int i = 0; i < currentVertices.Length; ++i)
        {
            currentVertices[i].Position = Vector3.Transform(currentVertices[i].Position, currentWorld);
        }
        vBuffer.SetData(currentVertices);
    }
}

Let the shader do it...one of the parameters of a shader is usually a WorldMatrix... 让着色器执行此操作...着色器的参数之一通常是WorldMatrix ...

to draw it: 画出来:

effect.Parameters["WorldMatrix"].SetValue(World);
effect.Apply(0);

if you have problems drawing a block... try to create a world transform matrix by yourself and test it... 如果您在绘制块时遇到问题,请尝试自己创建一个世界变换矩阵并对其进行测试。

effect.Parameters["WorldMatrix"].SetValue(Matrix.CreateRotationZ(angle));
effect.Apply(0);

If you have several instances of block, you can use instancing to pass the trasnform matrix in a vertexBuffer to the shader... 如果您有多个block实例,则可以使用实例化将vertexBuffer中的trasnform矩阵传递给着色器...

Here you can find info about instancing: http://blogs.msdn.com/b/shawnhar/archive/2010/06/17/drawinstancedprimitives-in-xna-game-studio-4-0.aspx 在这里您可以找到有关实例化的信息: http : //blogs.msdn.com/b/shawnhar/archive/2010/06/17/drawinstancedprimitives-in-xna-game-studio-4-0.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM