コード例 #1
0
    static float Evaluate(float value, MapRulesSettings mapRulesSettings)
    {
        float a = mapRulesSettings.slope;
        float b = mapRulesSettings.shift;

        return(Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a)));
    }
コード例 #2
0
    public static float[,] GenerateCornerFalloffMap(int size, MapRulesSettings mapRulesSettings, Corner corner)
    {
        float[,] map = new float[size, size];

        for (int i = 0; i < size / 2; i++)
        {
            for (int j = 0; j < size / 2; j++)
            {
                float x = i / (float)size * 2 - 1;
                float y = j / (float)size * 2 - 1;

                float value = Mathf.Max(Mathf.Abs(x), Mathf.Abs(y));
                map[i, j] = Evaluate(value, mapRulesSettings);
            }
        }

        for (int i = 0; i < size / 2; i++)
        {
            for (int j = size / 2; j < size; j++)
            {
                float x = i / (float)size * 2 - 1;

                float value = Mathf.Max(Mathf.Abs(x), 0);
                map[i, j] = Evaluate(value, mapRulesSettings);
            }
        }

        for (int j = 0; j < size / 2; j++)
        {
            for (int i = size / 2; i < size; i++)
            {
                float y = j / (float)size * 2 - 1;

                float value = Mathf.Max(0, Mathf.Abs(y));
                map[i, j] = Evaluate(value, mapRulesSettings);
            }
        }

        if (corner == Corner.BOTTOMLEFT)
        {
            Utils <float> .rotateMatrix(map);
        }
        else if (corner == Corner.BOTTOMRIGHT)
        {
            for (int i = 0; i < 2; i++)
            {
                Utils <float> .rotateMatrix(map);
            }
        }
        else if (corner == Corner.TOPRIGHT)
        {
            for (int i = 0; i < 3; i++)
            {
                Utils <float> .rotateMatrix(map);
            }
        }

        return(map);
    }
コード例 #3
0
    public static float[,] GenerateEdgeFalloffMap(int size, MapRulesSettings mapRulesSettings, Edge edge)
    {
        float[,] map = new float[size, size];

        int maxY;
        int maxX;
        int startX;
        int startY;

        if (edge == Edge.LEFT)
        {
            startX = 0;
            startY = 0;
            maxX   = size / 2;
            maxY   = size;
        }
        else if (edge == Edge.RIGHT)
        {
            startX = size / 2;
            startY = 0;
            maxX   = size;
            maxY   = size;
        }
        else if (edge == Edge.BOTTOM)
        {
            startX = 0;
            startY = size / 2;
            maxX   = size;
            maxY   = size;
        }
        else
        {
            // TOP SETTINGS
            startX = 0;
            startY = 0;
            maxX   = size;
            maxY   = size / 2;
        }

        bool isVertical = edge == Edge.LEFT || edge == Edge.RIGHT;

        for (int i = startY; i < maxY; i++)     // y
        {
            for (int j = startX; j < maxX; j++) // x
            {
                float x = i / (float)size * 2 - 1;
                float y = j / (float)size * 2 - 1;

                float value = isVertical ? Mathf.Max(0, Mathf.Abs(y)): Mathf.Max(Mathf.Abs(x), 0);
                map[i, j] = Evaluate(value, mapRulesSettings);
            }
        }

        return(map);
    }
コード例 #4
0
    public TerrainChunk(Vector2 coord, HeightMapSettings heightMapSettings, MeshSettings meshSettings, MapRulesSettings mapRulesSettings, LODInfo[] detailLevels, int colliderLODIndex, Transform parent, Transform viewer, Material material, ResourcePool resourcePool)
    {
        this.coord            = coord;
        this.detailLevels     = detailLevels;
        this.colliderLODIndex = colliderLODIndex;

        this.heightMapSettings = heightMapSettings;
        this.meshSettings      = meshSettings;
        this.mapRulesSettings  = mapRulesSettings;

        this.resourcePool = resourcePool;

        this.viewer = viewer;

        sampleCenter = coord * meshSettings.meshWorldSize / meshSettings.meshScale;
        Vector2 position = coord * meshSettings.meshWorldSize;

        bounds = new Bounds(position, Vector2.one * meshSettings.meshWorldSize);

        meshObject            = new GameObject("Terrain Chunk");
        meshObject.layer      = LayerMask.NameToLayer("Terrain");
        meshRenderer          = meshObject.AddComponent <MeshRenderer>();
        meshFilter            = meshObject.AddComponent <MeshFilter>();
        meshCollider          = meshObject.AddComponent <MeshCollider>();
        meshRenderer.material = material;

        meshObject.transform.position = new Vector3(position.x, 0, position.y);
        meshObject.transform.parent   = parent;

        SetVisible(false);

        lodMeshes = new LODMesh[detailLevels.Length];
        for (int i = 0; i < detailLevels.Length; i++)
        {
            lodMeshes[i] = new LODMesh(detailLevels[i].lod);
            lodMeshes[i].updateCallback += UpdateTerrainChunk;
            lodMeshes[i].updateCallback += GenerateResourceNodes;
            if (i == colliderLODIndex)
            {
                lodMeshes[i].updateCallback += UpdateCollisionMesh;
            }
        }

        maxViewDistance = detailLevels[detailLevels.Length - 1].visibleDistanceThreshold;
    }
コード例 #5
0
    public static float[,] GenerateFalloffMap(int size, MapRulesSettings mapRulesSettings)
    {
        float[,] map = new float[size, size];

        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                float x = i / (float)size * 2 - 1;
                float y = j / (float)size * 2 - 1;

                float value = Mathf.Max(Mathf.Abs(x), Mathf.Abs(y));
                map[i, j] = Evaluate(value, mapRulesSettings);
            }
        }

        return(map);
    }
コード例 #6
0
    public static HeightMap GenerateHeightMap(int width, int height, HeightMapSettings settings, MapRulesSettings mapRules, Vector2 sampleCenter, ChunkBorderInfo borderInfo)
    {
        float[,] values = Noise.GenerateNoiseMap(width, height, settings.noiseSettings, sampleCenter);

        AnimationCurve heightCurveThreadSafe = new AnimationCurve(settings.heightCurve.keys);

        float minValue = float.MaxValue;
        float maxValue = float.MinValue;

        if (mapRules.useFalloff)
        {
            float[,] falloffMap;

            if (mapRules.useFalloff)
            {
                if (mapRules.maxMapSizeInChunks.x <= 1 && mapRules.maxMapSizeInChunks.y <= 1)
                {
                    falloffMap = FalloffGenerator.GenerateFalloffMap(width, mapRules);
                }
                else if (borderInfo.isCorner)
                {
                    falloffMap = FalloffGenerator.GenerateCornerFalloffMap(width, mapRules, borderInfo.corner);
                }
                else if (borderInfo.isEdge)
                {
                    falloffMap = FalloffGenerator.GenerateEdgeFalloffMap(width, mapRules, borderInfo.edge);
                }
                else
                {
                    falloffMap = new float[width, height];
                }
            }
            else
            {
                falloffMap = new float[width, height];
            }

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    values[i, j] = Mathf.Clamp01(values[i, j] - falloffMap[i, j]);

                    values[i, j] *= heightCurveThreadSafe.Evaluate(values[i, j]) * settings.heightMultiplier;

                    if (values[i, j] > maxValue)
                    {
                        maxValue = values[i, j];
                    }
                    if (values[i, j] < minValue)
                    {
                        minValue = values[i, j];
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    values[i, j] = Mathf.Clamp01(values[i, j]);

                    values[i, j] *= heightCurveThreadSafe.Evaluate(values[i, j]) * settings.heightMultiplier;

                    if (values[i, j] > maxValue)
                    {
                        maxValue = values[i, j];
                    }
                    if (values[i, j] < minValue)
                    {
                        minValue = values[i, j];
                    }
                }
            }
        }

        return(new HeightMap(values, minValue, maxValue));
    }