渲染由飞机定义的立方体(阀门映射文件格式)

时间:2016-06-19 10:24:55

标签: c# 3d xna rendering monogame

目前我正在尝试在monogame应用程序中渲染一个多维数据集。 我正在使用Valve地图文件格式。地图格式在以下维基页面中描述:

https://developer.valvesoftware.com/wiki/MAP_file_format

直接导入格式并没有任何问题。 重要的部分是飞机的描述。格式如下:

{
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
    ( x1 y1 z1) ( x2 y2 z2) ( x3 y3 z3) texture_name  ...
}

每一行定义一个平面。要定义一个实际平面,必须给出三个点(由x1,y1,z1,x2,y2,z2和x3,y3,z3表示)。

plane ((vertex) (vertex) (vertex))

这定义了用于在三维世界中设置平面方向和位置的三个点。第一个标记在面的左下方,第二个标记在左上方,第三个标记在右上方。下面是通过CSG从六架飞机构建的简单画笔的动画。第一,第二和第三个平面点由红色,绿色和蓝色点表示。

Animation

所以我正在加载这些平面并将它们渲染为三角形。 我的monogame应用程序中的redering结果如下:

Rendering Result

很明显,多维数据集中缺少某些部分。

我正在使用worldcraft hammer编辑器创建地图文件。所以结果应该是这样的:

Worldcraft Hammer

顶点-创作-方法:

将画笔和面转换为xna VertexPositionColor类型。

    private VertexPositionColor[] CreateVertexPositions(Brush brush)
    {
        VertexPositionColor[] vertices = new VertexPositionColor[brush.Faces.Count * 3];

        int j = 0;
        for (int i = 0; i < brush.Faces.Count; i++)
        {
            Face brushFace = brush.Faces[i];
            Color color = ColorUtils.GenerateRandomColor(Color.Wheat);

            vertices[i + j + 0] = new VertexPositionColor( // bottom left of the face
                new Vector3(brushFace.V1.X, brushFace.V1.Y, brushFace.V1.Z), color
            );
            vertices[i + j + 1] = new VertexPositionColor( // top left of the face
                new Vector3(brushFace.V2.X, brushFace.V2.Y, brushFace.V2.Z), color
            );
            vertices[i + j + 2] = new VertexPositionColor( // top right of the face
                new Vector3(brushFace.V3.X, brushFace.V3.Y, brushFace.V3.Z), color
            );

            j = j + 2;
        }

        return vertices;
    }

BrushFace模型

public sealed class Face
{
    public Vertex3 V1 { get; set; }
    public Vertex3 V2 { get; set; }
    public Vertex3 V3 { get; set; }
    public string TextureName { get; set; }
    public Plane P1 { get; set; }
    public Plane P2 { get; set; }
    public int Rotation { get; set; }
    public float XScale { get; set; }
    public float YScale { get; set; }
}

渲染-方法

    public override void Render(ICamera camera)
    {
        _effect.Projection = camera.Projection;
        _effect.View = camera.View;
        _effect.World = camera.World;

        RasterizerState rasterizerState = new RasterizerState();
        rasterizerState.CullMode = CullMode.None;
        rasterizerState.FillMode = FillMode.Solid;
        GraphicsDevice.RasterizerState = rasterizerState;

        foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
        {
            pass.Apply();
            GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, _vertices.ToArray(), 0, (_vertices.Count / 3), VertexPositionColor.VertexDeclaration);
        }
    }

我错过了一件有趣的作品。如何从给定的平面创建一个立方体?

我不是要求一个完整的代码,也不是一个完整的解决方案,而是要求某人将我推向正确的方向。

提前谢谢。

更新

我为此制作了一个非常简单的项目并将其上传到我的OneDrive帐户:

OneDrive Link

1 个答案:

答案 0 :(得分:3)

立方体由6个四边形(6个矩形)组成。四边形是两个三角形,而不是一个。由于四边形是2个三角形,因此它有6个顶点。因此,要渲染立方体,您必须处理36个顶点。

构成36个顶点的所有信息都在构成你的飞机的18个顶点中。

对于所有36个顶点,只有6个唯一的组件值。对于构成立方体的36个顶点中的任何一个,只能有2个可能的X值,2个可能的Y值和2个可能的Z值。所有36个顶点都由这6个唯一值的各种组合组成。

您的任务是迭代6个平面(18个顶点)并拉出6个唯一的组件值,然后从这6个组件值中组成36个顶点。然后使用36个顶点填充VertexBuffer。