Marching Cubes在网格

时间:2017-06-26 12:47:05

标签: c# unity3d marching-cubes

我正在Unity中使用Marching Cubes实现。我的代码基于Paul Bourke的code实际上有很多修改,但无论如何我正在检查一个位置的块是否为空,如果它不是调试纹理将放在它上面。

Here is an image of the problem

这是我的MC脚本

    public class MarchingCubes
{
private World world;
private Chunk chunk;
private List<Vector3> vertices = new List<Vector3> ();
private List<Vector3> normals = new List<Vector3> ();
private Vector3[] ns;
private List<int> triangles = new List<int> ();
private List<Vector2> uvs = new List<Vector2> ();
private Vector3[] positions = new Vector3[8];
private float[] corners = new float[8];
private Vector3i size = new Vector3i (16, 128, 16);

Vector3[] vertlist = new Vector3[12];

private float isolevel = 1f;

private float Corner (Vector3i pos)
{
    int x = pos.x;
    int y = pos.y;
    int z = pos.z;
    if (x < size.x && z < size.z) {
        return chunk.GetValue (x, y, z);
    } else {
        int ix = chunk.X, iz = chunk.Z;
        int rx = chunk.region.x, rz = chunk.region.z;
        if (x >= size.x) {
            ix++;
            x = 0;
        }

        if (z >= size.z) {
            iz++;
            z = 0;
        }
        return chunk.region.GetChunk (ix, iz).GetValue (x, y, z);
    }
}

Block block;

public Mesh MarchChunk (World world, Chunk chunk, Mesh mesh)
{
    this.world = world;
    this.chunk = chunk;

    vertices.Clear ();
    triangles.Clear ();
    uvs.Clear ();

    for (int x = 0; x < size.x; x++) {
        for (int y = 1; y < size.y - 2; y++) {
            for (int z = 0; z < size.z; z++) {

                block = chunk.GetBlock (x, y, z);
                int cubeIndex = 0;

                for (int i = 0; i < corners.Length; i++) {
                    corners [i] = Corner (new Vector3i (x, y, z) + offset [i]);
                    positions [i] = (new Vector3i (x, y, z) + offset [i]).ToVector3 ();

                    if (corners [i] < isolevel)
                        cubeIndex |= (1 << i);
                }

                if (eTable [cubeIndex] == 0)
                    continue;

                for (int i = 0; i < vertlist.Length; i++) {
                    if ((eTable [cubeIndex] & 1 << i) == 1 << i)
                        vertlist [i] = LinearInt (positions [eCons [i, 0]], positions [eCons [i, 1]], corners [eCons [i, 0]], corners [eCons [i, 1]]);
                }

                for (int i = 0; triTable [cubeIndex, i] != -1; i += 3) {
                    int index = vertices.Count;

                    vertices.Add (vertlist [triTable [cubeIndex, i]]);
                    vertices.Add (vertlist [triTable [cubeIndex, i + 1]]);
                    vertices.Add (vertlist [triTable [cubeIndex, i + 2]]);

                    float tec = (0.125f);
                    Vector2 uvBase = block != null ? block.UV : new Vector2 ();

                    uvs.Add (uvBase);
                    uvs.Add (uvBase + new Vector2 (0, tec));
                    uvs.Add (uvBase + new Vector2 (tec, tec));

                    triangles.Add (index + 0);
                    triangles.Add (index + 1);
                    triangles.Add (index + 2);
                }
            }
        }
    }       

    if (mesh == null)
        mesh = new Mesh ();
    mesh.Clear ();
    mesh.vertices = vertices.ToArray ();
    mesh.triangles = triangles.ToArray ();
    mesh.uv = uvs.ToArray ();
    mesh.RecalculateNormals ();
    return mesh;
}

bool IsBitSet (int b, int pos)
{
    return ((b & pos) == pos);
}

Vector3 LinearInt (Vector3 p1, Vector3 p2, float v1, float v2)
{
    Vector3 p;
    p.x = p1.x + (isolevel - v1) * (p2.x - p1.x) / (v2 - v1);
    p.y = p1.y + (isolevel - v1) * (p2.y - p1.y) / (v2 - v1);
    p.z = p1.z + (isolevel - v1) * (p2.z - p1.z) / (v2 - v1);
    return p;
}

private static int[,] eCons = new int[12, 2] {
    { 0, 1 },
    { 1, 2 },
    { 2, 3 },
    { 3, 0 },
    { 4, 5 },
    { 5, 6 },
    { 6, 7 },
    { 7, 4 },
    { 0, 4 },
    { 1, 5 },
    { 2, 6 },
    { 3, 7 }
};

private static Vector3i[] offset = new Vector3i[8] {
    new Vector3i (0, 0, 1),
    new Vector3i (1, 0, 1),
    new Vector3i (1, 0, 0),
    new Vector3i (0, 0, 0),
    new Vector3i (0, 1, 1),
    new Vector3i (1, 1, 1),
    new Vector3i (1, 1, 0),
    new Vector3i (0, 1, 0)
};
  }

我没有将表格放在样本中,因为它们与Bourke代码中的表格相同。

编辑: 我想到的是,蓝色三角形的单元格值为0,因此它们不必进行三角测量,但单元格下的单元格值为1,因此创建了一个顶部三角形来完成网格。

0 个答案:

没有答案