示例#1
0
    /// <summary>
    /// <para>Compute the normals for each vertex of the mesh, checking the edges cells of other chunks.</para>
    /// <para>This process is needed to avoid illumination differences between contiguous cells of different chunks (seams).</para>
    /// </summary>
    /// <param name="chunk"></param>
    protected virtual void ComputeNormals(Chunk chunk)
    {
        chunk.Normals = new Vector3[(ChunkSize + 1) * (ChunkSize + 1)];
        int        i, triangleIdx, x, z;
        Vector2Int vertexTerrainPos;
        Vector3    a, b, c, normal;

        // Normal for each vertex
        for (i = 0; i < chunk.Vertices.Count; i++)
        {
            LC_Math.IndexToCoords(i, ChunkSize + 1, out x, out z);

            // If isn't edge
            if (x < ChunkSize && z < ChunkSize)
            {
                triangleIdx = LC_Math.CoordsToIndex(x, z, ChunkSize) * 6;
                CalculateTrianglesNormals(triangleIdx, chunk);
                CalculateTrianglesNormals(triangleIdx + 3, chunk);
            }
            // If is edge
            if (x == 0 || z == 0 || x >= ChunkSize || z >= ChunkSize)
            {
                vertexTerrainPos = chunk.ChunkPosToTerrain(new Vector2Int(x, z));
                a = chunk.Vertices[i];

                if (x == 0 || z == 0)
                {
                    b                 = TerrainPosToReal(vertexTerrainPos.x - 1, chunk.HeightsMap[x, z + 1], vertexTerrainPos.y);       // x - 1, z
                    c                 = TerrainPosToReal(vertexTerrainPos.x - 1, chunk.HeightsMap[x, z], vertexTerrainPos.y - 1);       // x - 1, z - 1
                    normal            = -Vector3.Cross(b - a, c - a);
                    chunk.Normals[i] += normal;
                    if (x != 0)
                    {
                        chunk.Normals[i - (ChunkSize + 1)] += normal;
                    }

                    b                 = c;                                                                                        // x - 1, z - 1
                    c                 = TerrainPosToReal(vertexTerrainPos.x, chunk.HeightsMap[x + 1, z], vertexTerrainPos.y - 1); // x, z - 1
                    normal            = -Vector3.Cross(b - a, c - a);
                    chunk.Normals[i] += normal;
                    if (z != 0)
                    {
                        chunk.Normals[i - 1] += normal;
                    }
                }
                if (x == ChunkSize || z == ChunkSize)
                {
                    b                 = TerrainPosToReal(vertexTerrainPos.x + 1, chunk.HeightsMap[x + 2, z + 1], vertexTerrainPos.y);       // x + 1, z
                    c                 = TerrainPosToReal(vertexTerrainPos.x + 1, chunk.HeightsMap[x + 2, z + 2], vertexTerrainPos.y + 1);   // x + 1, z + 1
                    normal            = -Vector3.Cross(b - a, c - a);
                    chunk.Normals[i] += normal;
                    if (x < ChunkSize)
                    {
                        chunk.Normals[i + (ChunkSize + 1)] += normal;
                    }

                    b                 = c;                                                                                            // x + 1, z + 1
                    c                 = TerrainPosToReal(vertexTerrainPos.x, chunk.HeightsMap[x + 1, z + 2], vertexTerrainPos.y + 1); // x, z + 1
                    normal            = -Vector3.Cross(b - a, c - a);
                    chunk.Normals[i] += normal;
                    if (z < ChunkSize)
                    {
                        chunk.Normals[i + 1] += normal;
                    }
                }
            }
        }

        for (i = 0; i < chunk.Normals.Length; i++)
        {
            chunk.Normals[i].Normalize();
        }
    }