顶点立方体旋转中心

时间:2013-10-25 10:02:13

标签: c# xna xna-4.0

如何找到使用顶点缓冲区制作的立方体的旋转中心? 立方体当前正在一个顶点上旋转,我整个星期都陷入困境,试图弄清楚如何将它调整到中心。

以下是我渲染多维数据集的代码:

class RenderCube
{

    KeyboardState currentKeys;
    GamePadState currentGamepad;

    //Transform later to have static v and i buffers.
    private VertexBuffer vBuffer;
    public VertexBuffer VBuffer
    { get { return vBuffer; } set { vBuffer = value; } }

    private IndexBuffer iBuffer;
    public IndexBuffer IBuffer
    { get { return iBuffer; } set { iBuffer = value; } }

    private BasicEffect bEffect;
    public BasicEffect BEffect
    { get { return bEffect; } set { bEffect = value; } }

    private Matrix world;
    public Matrix World
    { get { return world; } set { world = value; } }

    private Matrix view;
    public Matrix View
    { get { return view; } set { view = value; } }

    private Matrix projection;
    private Matrix Projection
    { get { return projection; } set { projection = value; } }

    private Color color;
    public Color Color
    { get { return color; } set { color = value; } }

    private Vector3 position;
    public Vector3 Position
    { get { return position; } set { position = value; } }

    //Need to change this eventually to use textures.
    private VertexPositionColor[] vertices;
    short[] indices;


    private GraphicsDevice device;
    //constructors!
    public RenderCube(Color col, Vector3 pos, GraphicsDevice dev)
    {
        device = dev;

        this.color = col;
        this.position = pos;
        SetUpVertices();
        SetUpIndices();

        world = Matrix.CreateTranslation(position);
        //world = Matrix.CreateTranslation(0, 0, 0);
        bEffect = new BasicEffect(device);
        bEffect.World = world;
        bEffect.VertexColorEnabled = true;
        //bEffect.EnableDefaultLighting();
    }

    public void Render(Camera cam)
    {
        bEffect.View = cam.view;
        bEffect.Projection = cam.projection;
        bEffect.World *= cam.rotX;
        bEffect.World *= cam.rotY;
        bEffect.World *= cam.rotZ;

        var rotationCenter = new Vector3(0.5f, 0.5f, 0.5f);

        device.SetVertexBuffer(vBuffer);
        device.Indices = IBuffer;

        foreach (EffectPass pass in bEffect.CurrentTechnique.Passes)
        {
            pass.Apply();
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 12);
        }
    }

    /// <summary>
    /// Sets up the vertices for a cube using 8 unique vertices.
    /// Build order is front to back, left to up to right to down.
    /// </summary>
    private void SetUpVertices()
    {
        vertices = new VertexPositionColor[8];

        //front left bottom corner
        vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), color);
        //front left upper corner
        vertices[1] = new VertexPositionColor(new Vector3(0, 100, 0), color);
        //front right upper corner
        vertices[2] = new VertexPositionColor(new Vector3(100, 100, 0), color);
        //front lower right corner
        vertices[3] = new VertexPositionColor(new Vector3(100, 0, 0), color);
        //back left lower corner
        vertices[4] = new VertexPositionColor(new Vector3(0, 0, -100), color);
        //back left upper corner
        vertices[5] = new VertexPositionColor(new Vector3(0, 100, -100), color);
        //back right upper corner
        vertices[6] = new VertexPositionColor(new Vector3(100, 100, -100), color);
        //back right lower corner
        vertices[7] = new VertexPositionColor(new Vector3(100, 0, -100), color);

        vBuffer = new VertexBuffer(device, typeof(VertexPositionColor), 8, BufferUsage.WriteOnly);
        vBuffer.SetData<VertexPositionColor>(vertices);
    }

    /// <summary>
    /// Sets up the indices for a cube. Has 36 positions that match up
    /// to the element numbers of the vertices created earlier.
    /// Valid range is 0-7 for each value.
    /// </summary>
    private void SetUpIndices()
    {
        indices = new short[36];

        //Front face
        //bottom right triangle
        indices[0] = 0;
        indices[1] = 3;
        indices[2] = 2;
        //top left triangle
        indices[3] = 2;
        indices[4] = 1;
        indices[5] = 0;
        //back face
        //bottom right triangle
        indices[6] = 4;
        indices[7] = 7;
        indices[8] = 6;
        //top left triangle
        indices[9] = 6;
        indices[10] = 5;
        indices[11] = 4;
        //Top face
        //bottom right triangle
        indices[12] = 1;
        indices[13] = 2;
        indices[14] = 6;
        //top left triangle
        indices[15] = 6;
        indices[16] = 5;
        indices[17] = 1;
        //bottom face
        //bottom right triangle
        indices[18] = 4;
        indices[19] = 7;
        indices[20] = 3;
        //top left triangle
        indices[21] = 3;
        indices[22] = 0;
        indices[23] = 4;
        //left face
        //bottom right triangle
        indices[24] = 4;
        indices[25] = 0;
        indices[26] = 1;
        //top left triangle
        indices[27] = 1;
        indices[28] = 5;
        indices[29] = 4;
        //right face
        //bottom right triangle
        indices[30] = 3;
        indices[31] = 7;
        indices[32] = 6;
        //top left triangle
        indices[33] = 6;
        indices[34] = 2;
        indices[35] = 3;

        iBuffer = new IndexBuffer(device, IndexElementSize.SixteenBits, sizeof(short) * indices.Length, BufferUsage.WriteOnly);
        iBuffer.SetData(indices);
    }
}

1 个答案:

答案 0 :(得分:0)

基本思想是引入一个翻译矩阵,将立方体推送到原点,执行旋转并撤消翻译:

public void Render(Camera cam)
{
    //...
    //push the cube to the origin
    bEffect.World *= Matrix.CreateTranslation(-50, -50, 50); 
    //perform the rotation
    bEffect.World *= cam.rotX;
    bEffect.World *= cam.rotY;
    bEffect.World *= cam.rotZ;
    //undo the translation
    bEffect.World *= Matrix.CreateTranslation(50, 50, -50);
    //...