Beispiel #1
0
    static void UpdateVertexesOnRange(WorldChunk chunk,
                                      int min_x, int max_x, int min_y, int max_y,
                                      int[,] vertexIndicesMap, int meshSize, int borderedSize, float offset,
                                      WorldChunkSettings setting)
    {
        for (int y = min_y; y < max_y; y++)
        {
            for (int x = min_x; x < max_x; x++)
            {
                Coord chunkCoord = new Coord(x - 1, y - 1, setting);                  // It's start with [-1;-1]

                int vertexIndex = vertexIndicesMap [x, y];

                // @TODO We already know the concerned sideChunk (it's `keyValue.Value` on `UpdateChunkMesh` loop
                // (can be pass throw GetHeightValue to avoid search it on the list)
                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
                    );
                chunk.meshData.AddOrUpdateVertex(vertexPosition, uv, vertexIndex);
            }
        }
    }
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
    // Get Height map as saved:
    // Size: 50x50  - Scale: 10 -> coord from [0;0] to [5;5]
    // coord can be on a side chunk (ex x:-1 or y:setting.scaledSize), return sidechunk value he's merged
    public float GetHeightValue(Coord coord, WorldChunkSettings setting)
    {
        if (this.state < ChunkStates.Merged)
        {
            return(0f);
        }
        // It's on a side chunk, get the chunk and the right coord
        if (coord.x < 0 || coord.y < 0 || coord.x >= setting.scaledSize || coord.y >= setting.scaledSize)
        {
            Coord chunkCoord = new Coord(this.coord.x, this.coord.y);
            if (coord.x < 0)
            {
                chunkCoord.x += Coord.Left.x;                 // x--
            }
            else if (coord.x >= setting.scaledSize)
            {
                chunkCoord.x += Coord.Right.x;                 // x++
            }
            if (coord.y < 0)
            {
                chunkCoord.y += Coord.Bottom.y;                 // y--
            }
            else if (coord.y >= setting.scaledSize)
            {
                chunkCoord.y += Coord.Top.y;                 // y++
            }
            // The chunk is loaded AND merged
            if (this.chunkBorders.sidesChunks.ContainsKey(chunkCoord))
            {
                WorldChunk sideChunk = this.chunkBorders.sidesChunks [chunkCoord];
                if (sideChunk.state >= ChunkStates.Merged)
                {
                    if (coord.x < 0)
                    {
                        coord.x += setting.scaledSize;
                    }
                    else if (coord.x >= setting.scaledSize)
                    {
                        coord.x -= setting.scaledSize;
                    }
                    if (coord.y < 0)
                    {
                        coord.y += setting.scaledSize;
                    }
                    else if (coord.y >= setting.scaledSize)
                    {
                        coord.y -= setting.scaledSize;
                    }
                    return(sideChunk.GetHeightValue(coord, setting));
                }
            }
            // The chunk isn't loaded.. take the nearest on the same chunk by updating the coord requested
            if (coord.x < 0)
            {
                coord.x = 0;
            }
            else if (coord.x >= setting.scaledSize)
            {
                coord.x = setting.scaledSize - 1;
            }
            if (coord.y < 0)
            {
                coord.y = 0;
            }
            else if (coord.y >= setting.scaledSize)
            {
                coord.y = setting.scaledSize - 1;
            }
        }

        // Reset index, cause x/y may was updated
        coord.SetIndex(setting);

        float     noiseHeight = this.chunkData.GetHeightValue(coord);
        WorldZone zone        = this.chunkComputed.GetZone(coord).worldZoneRef;

        return(MeshGenerator.GetRealHeight(noiseHeight, zone.type, setting));
    }