public void RequestWorldChunkMeshData(WorldChunk chunk, WorldChunkSideBorders sideBorder, WorldChunkSettings setting, Action <MeshData> callback)
    {
        ThreadStart threadStart = delegate {
            // Loading
            MeshData meshData = MeshGenerator.GenerateWorldChunkMesh(chunk, sideBorder, setting);
            lock (chunkMeshThreadInQueue) {
                chunkMeshThreadInQueue.Enqueue(new MeshDataThreadInfo <MeshData>(callback, meshData));
            }
            // End Loading..
        };

        new Thread(threadStart).Start();
    }
Beispiel #2
0
    public static MeshData GenerateWorldChunkMesh(WorldChunk chunk, WorldChunkSideBorders borders, WorldChunkSettings setting)
    {
        int   size         = setting.scaledSize;
        int   meshSize     = size + 1;     // One line on top/left to create the triangles between chunks
        int   borderedSize = meshSize + 2; // One line on every direction to calculate normals of triangle on the border of mesh
        float offset       = (meshSize - 1) / -2f;

        MeshData meshData = new MeshData(meshSize);

        // To handle normals, the mesh have to generate vertices for 1line on each 8chunks bordered
        int[,] vertexIndicesMap = CreateVertexIndicesMap(borderedSize);

        for (int y = 0; y < borderedSize; y++)
        {
            for (int x = 0; x < borderedSize; x++)
            {
                Coord chunkCoord = new Coord(x - 1, y - 1, setting);              // It's start with [-1;-1]

                int   vertexIndex = vertexIndicesMap [x, y];
                float height      = chunk.GetHeightValue(chunkCoord, setting);

                Vector2 uv             = new Vector2((x - 1) / (float)(borderedSize - 2), (y - 1) / (float)(borderedSize - 2));
                Vector3 vertexPosition = new Vector3(
                    offset + uv.x * meshSize,
                    height,
                    offset + uv.y * meshSize
                    );
                meshData.AddOrUpdateVertex(vertexPosition, uv, vertexIndex);

                if (x <= borderedSize - 2 && y <= borderedSize - 2)
                {
                    int a = vertexIndicesMap[x, y];
                    int b = vertexIndicesMap[x + 1, y];
                    int c = vertexIndicesMap[x, y + 1];
                    int d = vertexIndicesMap[x + 1, y + 1];

                    // Clockwise
                    //		meshData.AddTriangle (a, d, c);
                    //		meshData.AddTriangle (d, a, b);
                    // Counter Clockwise
                    meshData.AddTriangle(c, d, a);
                    meshData.AddTriangle(b, a, d);
                }
            }
        }

        return(meshData);
    }
Beispiel #3
0
    public void OnChunkMerged()
    {
        WorldChunkSettings setting = MapEngine.instance.worldChunkSetting;

        this.state = ChunkStates.Merged;
        if (this.requireState < ChunkStates.Merged)           // If all the chunk is merged but wasn't required for (ex: side chunk with not border)
        {
            this.requireState = ChunkStates.Merged;
        }
        MapDisplay.instance.UpdateChunkDisplay(this);
        this.isMeshing = true;
        // Create the first time the chunk borders values
        this.chunkBorders = new WorldChunkSideBorders(this, setting);
        // Request Mesh data
        MapThreading.instance.RequestWorldChunkMeshData(this, this.chunkBorders, setting, OnWorldChunkMeshReceived);
    }