void OnGUI()
    {
        WorldChunkSettings setting = MapEngine.instance.worldChunkSetting;
        Coord viewer = new Coord(Viewer.instance.bound.center, setting);

        GUI.color = Color.black;
        GUI.Label(new Rect(10f, 30f, 250f, 30f), viewer + " - " + Viewer.instance.scale + ": " + GetChunkLevel(Viewer.instance.scale));
        float y = 50f;

        if (/* Display all zones ? */ false)
        {
            for (int i = 0; i < this.worldZones.Count; i++)
            {
                y = this.OnGUIZone(this.worldZones [i], y);
            }
        }
        else
        {
            Bounds     viewerBound      = Viewer.instance.bound;
            Coord      viewerChunkCoord = new Coord(viewerBound.center, setting);
            WorldChunk chunk            = this.worldChunks [viewerChunkCoord];
            for (int i = 0; i < chunk.worldZonesRefs.Count; i++)
            {
                y = this.OnGUIZone(chunk.worldZonesRefs[i], y);
            }
        }
    }
Example #2
0
    public void TestMerged(WorldChunkSettings setting)
    {
        if (this.state >= ChunkStates.Merged)
        {
            return;             //done
        }

        bool allZonesMerged           = true;
        bool onlySmallGroundRemaining = true;

        for (int idx = 0; idx < this.worldZonesRefs.Count; idx++)
        {
            WorldZone zone = this.worldZonesRefs [idx];
            if (zone.state < WorldZoneStates.Merged)
            {
                allZonesMerged = false;

                if (zone.type != WorldZoneTypes.Ground)
                {
                    //	onlySmallGroundRemaining = false;
                }
            }
        }

        if (allZonesMerged)
        {
            this.OnChunkMerged();
        }
    }
Example #3
0
    public void UpdateMapShader()
    {
        WorldChunkSettings setting = MapEngine.instance.worldChunkSetting;

        this.mapTextureData.UpdateStartHeights(setting);
        this.mapTextureData.ApplyOnMaterial(this.chunkMeshMaterial);
    }
    // setting already retrieved when new Chunk are created
    public WorldChunkData(WorldChunk chunk, WorldChunkSettings setting)
    {
        DevNoiseType devNoiseType = MapEndless.instance.devNoiseType;

        // Get Height Map
        FastNoise fastNoiseGround = setting.fastNoiseGround.fastNoise;
        FastNoise fastNoiseRegion = setting.fastNoiseRegion.fastNoise;
        int       length          = setting.scaledSize * setting.scaledSize;
        int       chunkOffsetX    = chunk.coord.x * setting.scaledSize - (setting.scaledSize / 2);
        int       chunkOffsetY    = chunk.coord.y * setting.scaledSize - (setting.scaledSize / 2);

        this.heightMap = new float[length];
        this.regionMap = new float[length];
        for (int y = 0; y < setting.scaledSize; y++)
        {
            for (int x = 0; x < setting.scaledSize; x++)
            {
                // Test and return only a mountain on [1;1] to [9;1]
                Coord c = new Coord(x, y, setting);

                if (devNoiseType != DevNoiseType.NoDev)
                {
                    // Use dev noise
                    this.heightMap [c.idx] = this.getZonesHeightTest(new Coord(c.x + chunkOffsetX, c.y + chunkOffsetY), devNoiseType);
                }
                else
                {
                    // Use fastNoiseGround
                    this.heightMap [c.idx] = (fastNoiseGround.GetNoise(c.x + chunkOffsetX, c.y + chunkOffsetY) + 1f) / 2f;
                }
                this.regionMap [c.idx] = (fastNoiseRegion.GetNoise(c.x + chunkOffsetX, c.y + chunkOffsetY) + 1f) / 2f;
            }
        }
    }
Example #5
0
    public WorldChunk(Coord _coord, GameObject _chunkObject, WorldChunkSettings setting, DisplayModes _displayMode, ChunkStates _requireState)
    {
        this.coord        = _coord;
        this.state        = ChunkStates.Created;
        this.displayMode  = _displayMode;
        this.isVisible    = false;
        this.isLoading    = false;
        this.isComputing  = false;
        this.isMeshing    = false;
        this.requireState = _requireState;

        this.chunkObject = _chunkObject;
        this.chunkObject.transform.parent        = setting.parent;
        this.chunkObject.transform.localScale    = new Vector3(setting.size, .01f, setting.size);
        this.chunkObject.transform.localPosition = this.coord.ToWorldPosition(setting);
        MapDisplay.instance.UpdateChunkName(this, setting);

        // Request Data
        if (this.requireState >= ChunkStates.Loaded)
        {
            this.requestData(setting);
        }
        else
        {
            MapDisplay.instance.UpdateChunkDisplay(this);
        }
    }
Example #6
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);
            }
        }
    }
Example #7
0
 public void requestComputed(WorldChunkSettings setting)
 {
     // Request Data
     this.isComputing   = true;
     this.computingTime = Time.time;
     MapThreading.instance.RequestWorldChunkComputed(this, setting, OnWorldChunkComputedReceived);
 }
    public float GetRegionScaledValue(Coord coord, WorldChunkSettings setting)
    {
        Coord scaledCoord = new Coord(
            coord.x / setting.scaledSize,
            coord.y / setting.scaledSize,
            setting);

        return(this.GetRegionValue(scaledCoord));
    }
Example #9
0
 public Vector3 ToWorldPosition(WorldChunkSettings setting)
 {
     // Reverse if required (from Coord X/Y to Unity X/Y 3D World)
     return(new Vector3(
                this.x * setting.size * Coord.Right.x,   // * Coord.Right.x to reverse world X and chunk X (if required)
                0f,
                this.y * setting.size * Coord.Top.y      // * Coord.Top.y to reverse world Y and chunk Y (if required)
                ));
 }
Example #10
0
 public void CreateWorldChunks(WorldChunkSettings settings)
 {
     // iterate through generation amount
     for (int i = 0; i < settings.amount; i++)
     {
         // create new chunk
         CreateWorldChunk(settings);
     }
 }
Example #11
0
    // Merge all zone from this chunk and all sideChunk
    // Will be called one time and another time reversed (to found fakezone and ground zone who need to be merged with MainGround)
    void MergeSideChunk(Direction direction, WorldChunk sideChunk, WorldChunkSettings setting)
    {
        Direction inverseDirection = Coord.GetDirectionInverse(direction);

        for (int chunkZone_idx = this.chunkComputed.zones.Count - 1; chunkZone_idx >= 0; chunkZone_idx--)
        {
            WorldChunkComputed.WorldChunkZone chunkZone = this.chunkComputed.zones [chunkZone_idx];

            if (chunkZone.worldZoneRef.isMainGround)
            {
                continue;                 // Don't merge MainGround into another
            }

            // Found a zone who need to be merged on direction (and it's not already done ? we repass here when reverse)
            if (chunkZone.isDirectionChunkBorder [direction] && chunkZone.missingChunks.Contains(sideChunk.coord))
            {
                bool machingFound = false;

                for (int sideChunkZone_idx = sideChunk.chunkComputed.zones.Count - 1; sideChunkZone_idx >= 0; sideChunkZone_idx--)
                {
                    WorldChunkComputed.WorldChunkZone sideChunkZone = sideChunk.chunkComputed.zones [sideChunkZone_idx];

                    if (!sideChunkZone.isDirectionChunkBorder [inverseDirection])
                    {
                        continue;
                    }
                    if (!sideChunkZone.missingChunks.Contains(this.coord))
                    {
                        continue;
                    }
                    if (sideChunkZone.type != chunkZone.type)
                    {
                        continue;
                    }

                    if (this.MergeIfMatchingCoords(chunkZone, direction, sideChunk, sideChunkZone, setting))
                    {
                        machingFound = true;
                    }
                }

                // IT's a fake bordered zone ! Some coord are on the limit of the chunk but no one on the next
                if (!machingFound && !chunkZone.worldZoneRef.isMainGround)
                {
                    chunkZone.missingChunks.Remove(sideChunk.coord);
                    chunkZone.isDirectionChunkBorder [direction] = false;
                    chunkZone.directionChunkBorderCoords [direction].Clear();

                    /* done by sideChunk.SeeMore()
                     * if (chunkZone.worldZoneRef.GetMissingChunks ().Count == 0) {
                     *      chunkZone.worldZoneRef.OnMergeCompleted ();
                     * }*/
                }
            }
        }
    }
    // Get Scaled data (real in game coord)
    // Size: 50x50  - Scale: 10 -> coord from [0;0] to [50;50]
    public float GetHeightScaledValue(Coord coord, WorldChunkSettings setting)
    {
        //int sizeScaled = setting.size / setting.scale;
        Coord scaledCoord = new Coord(
            coord.x / setting.scaledSize,
            coord.y / setting.scaledSize,
            setting);

        return(this.GetHeightValue(scaledCoord));
    }
Example #13
0
 public void Unload(WorldChunkSettings setting)
 {
     this.isVisible = false;
     if (MapDisplay.instance.displayFogOfWar == true)
     {
         Renderer renderer = this.chunkObject.GetComponent <Renderer> ();
         renderer.material.color = Color.gray;
     }
     MapDisplay.instance.UpdateChunkName(this, setting);
 }
Example #14
0
 public void DeleteWorldChunks(WorldChunkSettings settings)
 {
     // while not empty
     while (settings.chunks.Count != 0)
     {
         // destroy gameobject
         Destroy(settings.chunks [0]);
         // delete node
         settings.chunks.RemoveAt(0);
     }
 }
Example #15
0
 public void DeleteWorldChunk(WorldChunkSettings settings, int index)
 {
     // check index range
     if (index > -1)
     {
         // destroy gameobject
         Destroy(settings.chunks [index]);
         // remove node
         settings.chunks.RemoveAt(index);
     }
 }
Example #16
0
 public void DeleteWorldChunk(WorldChunkSettings settings, GameObject obj)
 {
     // check if null
     if (obj != null)
     {
         // destroy gameobject
         Destroy(obj);
         // remove node
         settings.chunks.Remove(obj);
     }
 }
    void CreateMeshAndUpdateSideMeshs(WorldChunk chunk, WorldChunkSettings setting)
    {
        //GameObject meshObjectContainer = new GameObject();
        chunk.meshObject = new GameObject();
        MeshRenderer renderer = chunk.meshObject.AddComponent <MeshRenderer> ();
        MeshFilter   filter   = chunk.meshObject.AddComponent <MeshFilter> ();

        filter.mesh                   = chunk.meshData.CreateMesh();
        renderer.material             = MapDisplay.instance.chunkMeshMaterial;
        renderer.material.mainTexture = TextureGenerator.WorldMergingTexture(chunk, setting);
        // @TODO: Why do I have to do that ? Texture are 1coord too big for mesh, but are good for chunk (on dev cube)
        float textureScale = 1f + (1f / setting.scaledSize);

        renderer.material.mainTextureScale = new Vector2(textureScale, textureScale);

        /*	DisplayMeshFilterNormals displayMeshFilterNormals = chunk.meshObject.AddComponent<DisplayMeshFilterNormals> ();
         *      displayMeshFilterNormals.normalLength = setting.size / 10f;
         *      displayMeshFilterNormals.normalColor = Color.black;*/
        /*
         * meshObjectContainer.transform.name = chunk.coord.ToString();
         * meshObjectContainer.transform.parent = setting.meshParent;
         * meshObjectContainer.transform.localPosition = chunk.coord.ToWorldPosition (setting);
         */
        //	chunk.meshObject.transform.parent = meshObjectContainer.transform;
        chunk.meshObject.transform.parent = setting.meshParent;
        chunk.meshObject.transform.name   = chunk.coord.ToString();

        chunk.meshObject.transform.localPosition = chunk.coord.ToWorldPosition(setting);         //Vector3.zero;
        // Why ? setting.scaledSize
        chunk.meshObject.transform.localScale = new Vector3(setting.size / setting.scaledSize, setting.size, setting.size / setting.scaledSize);


        // If any sides chunks are loaded, update it
        for (int y = chunk.coord.y - 1; y <= chunk.coord.y + 1; y++)
        {
            for (int x = chunk.coord.x - 1; x <= chunk.coord.x + 1; x++)
            {
                if (x == chunk.coord.x && y == chunk.coord.y)
                {
                    continue;
                }
                Coord sideCoord = new Coord(x, y);
                if (chunk.chunkBorders.sidesChunks.ContainsKey(sideCoord))
                {
                    WorldChunk sideChunk = chunk.chunkBorders.sidesChunks [sideCoord];
                    if (sideChunk.state >= ChunkStates.Meshed)
                    {
                        MeshGenerator.UpdateChunkMesh(sideChunk, setting);
                    }
                }
            }
        }
    }
    void UpdateCursor(WorldChunk _chunk, WorldChunkSettings setting, WorldChunkZone zone, Coord coord, Coord lastCoordDirection)
    {
        this.countTest++;
        if (coord.x < 0 || coord.y < 0 || coord.x >= setting.scaledSize || coord.y >= setting.scaledSize)
        {
            // Is out of chunk!
            return;
        }
        // First already contains on the current zone (ex: [0;0] -> [0;1] -> [0;0] will append offen)
        if (zone.coords.Contains(coord))
        {
            return;
        }
        // Test zone type (get the type based on heightMap)
        WorldZoneTypes coordType = _chunk.chunkData.GetZoneType(coord, setting);

        if (coordType != zone.type)
        {
            // It's not the same region (add it only one time)
            if (!this.HasZone(coord) && !this.availableCoords.Contains(coord))
            {
                this.availableCoords.Add(coord);
            }
            return;
        }

        // It's a new on the same zone, add
        zone.AddCoord(coord, setting);
        // If the coord is on the free coord list (for future next list)
        if (this.availableCoords.Contains(coord))
        {
            this.availableCoords.Remove(coord);
        }

        // Test all sides (but avoid returning on same than previous)
        if (lastCoordDirection != Coord.Top)
        {
            UpdateCursor(_chunk, setting, zone, coord.GetDirection(Direction.Top), Coord.Bottom);
        }
        if (lastCoordDirection != Coord.Bottom)
        {
            UpdateCursor(_chunk, setting, zone, coord.GetDirection(Direction.Bottom), Coord.Top);
        }
        if (lastCoordDirection != Coord.Left)
        {
            UpdateCursor(_chunk, setting, zone, coord.GetDirection(Direction.Left), Coord.Right);
        }
        if (lastCoordDirection != Coord.Right)
        {
            UpdateCursor(_chunk, setting, zone, coord.GetDirection(Direction.Right), Coord.Left);
        }
        return;
    }
    public static Texture2D WorldChunkStatesTexture(WorldChunk chunk, WorldChunkSettings setting)
    {
        Color loaded   = new Color(.2f, .2f, 1f);
        Color computed = new Color(.2f, 1f, .2f);
        Color merging  = new Color(1f, .2f, .2f);
        Color merged   = new Color(1f, .9f, .2f);

        Color groundMin = new Color(.25f, .25f, .25f);
        Color groundMax = new Color(.75f, .75f, .75f);

        Color[] colourMap = new Color[setting.scaledSize * setting.scaledSize];
        for (int y = 0; y < setting.scaledSize; y++)
        {
            for (int x = 0; x < setting.scaledSize; x++)
            {
                Coord c      = new Coord(x, y, setting);
                float height = chunk.chunkData.GetHeightValue(c);
                if (chunk.state == ChunkStates.Loaded)
                {
                    colourMap [y * setting.scaledSize + x] = Color.Lerp(Color.black, Color.white, height) * loaded;
                }
                else if (chunk.state >= ChunkStates.Computed)
                {
                    // idx: y * size + x
                    Color state = computed;
                    if (chunk.state == ChunkStates.Computed && chunk.requireState > ChunkStates.Computed)
                    {
                        state = merging;
                    }
                    else if (chunk.state >= ChunkStates.Merged)
                    {
                        state = merged;
                    }

                    if (height < setting.water)
                    {
                        colourMap [y * setting.scaledSize + x] = Color.white * state;
                    }
                    else if (height > setting.mountain)
                    {
                        colourMap [y * setting.scaledSize + x] = Color.black * state;
                    }
                    else
                    {
                        float delta = (height - setting.water) * (1 / (setting.mountain - setting.water));
                        colourMap [y * setting.scaledSize + x] = Color.Lerp(groundMax, groundMin, delta) * state;
                    }
                }
            }
        }
        return(TextureGenerator.TextureFromColorMap(colourMap, setting.scaledSize));
    }
    public void RequestWorldChunkComputed(WorldChunk chunk, WorldChunkSettings setting, Action <WorldChunkComputed> callback)
    {
        ThreadStart threadStart = delegate {
            // Loading
            WorldChunkComputed chunkComputed = new WorldChunkComputed(chunk, setting);
            lock (chunkComputedThreadInQueue) {
                chunkComputedThreadInQueue.Enqueue(new MapComputingThreadInfo <WorldChunkComputed>(callback, chunkComputed));
            }
            // End Loading..
        };

        new Thread(threadStart).Start();
    }
Example #21
0
    public void CreateWorldChunk(WorldChunkSettings settings)
    {
        // initialize variables
        int     index    = settings.chunks.Count;
        Vector3 position = new Vector3(0, 0, 0);

        if (settings.chunks.Count > 0)
        {
            position = settings.chunks [settings.chunks.Count - 1].transform.position;
        }
        // instantiate new object
        settings.chunks.Add(Instantiate(settings.prefabs[0], position + Vector3.up * settings.offset, new Quaternion(), settings.container));
    }
    public void RequestWorldChunkData(WorldChunk chunk, WorldChunkSettings setting, Action <WorldChunkData> callback)
    {
        ThreadStart threadStart = delegate {
            // Loading
            WorldChunkData chunkData = new WorldChunkData(chunk, setting);

            lock (chunkDataThreadInQueue) {
                chunkDataThreadInQueue.Enqueue(new MapThreadInfo <WorldChunkData>(callback, chunkData));
            }
            // End Loading..
        };

        new Thread(threadStart).Start();
    }
    // This function have to be here because return is based on HeightMap ! And have NO considaration on computed zones
    // Will be called to create a new zone from this coord
    public WorldZoneTypes GetZoneType(Coord coord, WorldChunkSettings setting)
    {
        float heightValue = this.GetHeightValue(coord, setting);

        if (heightValue < setting.water)
        {
            return(WorldZoneTypes.Water);
        }
        else if (heightValue > setting.mountain)
        {
            return(WorldZoneTypes.Mountain);
        }
        return(WorldZoneTypes.Ground);
    }
    public WorldChunkComputed(WorldChunk _chunk, WorldChunkSettings setting)
    {
        // Init attribute
        this.isCompleted = false;
        this.zones       = new List <WorldChunkZone>();

        // List all coord found next to found zones, an easy way to know here to start a new zone
        this.availableCoords.Add(new Coord(0, 0));        // Init first zone at [0;0] (all chunk have a 00)

        // Loop to find all zones on the chunk
        this.FindNewZone(_chunk, setting);
        this.isCompleted = true;         // Before Clean zone (ex: Ground -> MainGround)
        this.CleanZones(_chunk, setting);
    }
        public void AddCoord(Coord coord, WorldChunkSettings setting)
        {
            this.coords.Add(coord);

            // Test chunks sides for each directions
            for (int e = 0; e < Coord.directions.Length; e++)
            {
                if (coord.IsOnChunkBorder(Coord.directions[e], setting))
                {
                    isDirectionChunkBorder [Coord.directions [e]] = true;
                    directionChunkBorderCoords [Coord.directions [e]].Add(coord.GetBorderValue(Coord.directions [e]));                       // Every coord who are not really bordered will be removed on future
                }
            }
        }
 void FindNewZone(WorldChunk _chunk, WorldChunkSettings setting)
 {
     // Coord found
     if (availableCoords.Count > 0)
     {
         Coord firstNotInZone = availableCoords [0];
         // Create a new zone based on this coord
         WorldChunkZone zone = new WorldChunkZone(_chunk.chunkData.GetZoneType(firstNotInZone, setting));
         this.zones.Add(zone);
         this.UpdateCursor(_chunk, setting, zone, firstNotInZone, new Coord(0, 0));
         // Zone computed, check for next
         this.FindNewZone(_chunk, setting);
     }
 }
Example #27
0
    public void UpdateSideBorders(WorldChunk chunk, WorldChunkSettings setting)
    {
        for (int y = chunk.coord.y - 1; y <= chunk.coord.y + 1; y++)
        {
            for (int x = chunk.coord.x - 1; x <= chunk.coord.x + 1; x++)
            {
                if (x == chunk.coord.x && y == chunk.coord.y)
                {
                    continue;
                }
                Coord c = new Coord(x, y, setting);
                // Already found, dont copy again an again
                if (!this.sidesChunks.ContainsKey(c))
                {
                    if (MapEndless.instance.worldChunks.ContainsKey(c))
                    {
                        WorldChunk sideChunk = MapEndless.instance.worldChunks [c];
                        if (sideChunk.state >= ChunkStates.Merged)
                        {
                            this.sidesChunks [c] = sideChunk;
                        }
                    }
                }
            }
        }

        // DEV
        if (chunk.meshObject != null)
        {
            // Do it after all
            string dev = "";
            for (int y = chunk.coord.y - 1; y <= chunk.coord.y + 1; y++)
            {
                for (int x = chunk.coord.x - 1; x <= chunk.coord.x + 1; x++)
                {
                    if (x == chunk.coord.x && y == chunk.coord.y)
                    {
                        continue;
                    }
                    Coord c = new Coord(x, y, setting);
                    if (this.sidesChunks.ContainsKey(c))
                    {
                        dev += " " + c;
                    }
                }
            }
            chunk.meshObject.transform.name = chunk.coord + ((dev != "") ? (" is normalized with " + dev) : "");
        }
    }
    // When data are received from chunk
    public void OnWorldChunkThreadReceived(WorldChunk _chunk)
    {
        // Get the info that a chunk is Loaded. (in case it's not on bound)
        this.worldChunksInView.Add(_chunk);
        WorldChunkSettings setting = MapEngine.instance.worldChunkSetting;

        if (_chunk.state == ChunkStates.Computed)
        {
            this.CreateWorldZones(_chunk, setting);
            // Will be updated after TryMergeZone
        }
        if (_chunk.state == ChunkStates.Meshed)
        {
            this.CreateMeshAndUpdateSideMeshs(_chunk, setting);
        }
    }
Example #29
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);
    }
    public static Texture2D WorldZonesMergingTexture(WorldChunk chunk, WorldChunkSettings setting)
    {
        Color groundMin = new Color(.25f, .25f, .25f);
        Color groundMax = new Color(.75f, .75f, .75f);

        Color[] colourMap = new Color[setting.scaledSize * setting.scaledSize];
        bool[]  isOnZone  = new bool[setting.scaledSize * setting.scaledSize];

        for (int idx = 0; idx < chunk.worldZonesRefs.Count; idx++)
        {
            // Only display Completed
            //if (chunk.worldZonesRefs [idx].isCompleted) {
            // Be sure this Wolrd zone contain this chunk
            if (chunk.worldZonesRefs [idx].chunkZones.ContainsKey(chunk.coord))
            {
                for (int chunk_zone_idx = 0; chunk_zone_idx < chunk.worldZonesRefs [idx].chunkZones[chunk.coord].Count; chunk_zone_idx++)
                {
                    WorldChunkComputed.WorldChunkZone zone = chunk.worldZonesRefs [idx].chunkZones[chunk.coord] [chunk_zone_idx];
                    foreach (Coord c in zone.coords)
                    {
                        if (zone.type == WorldZoneTypes.Water || zone.type == WorldZoneTypes.Mountain)
                        {
                            isOnZone [c.y * setting.scaledSize + c.x]  = true;
                            colourMap [c.y * setting.scaledSize + c.x] = zone.worldZoneRef.randomColor;
                        }
                    }
                }
            }
            //}
        }
        for (int y = 0; y < setting.scaledSize; y++)
        {
            for (int x = 0; x < setting.scaledSize; x++)
            {
                if (!isOnZone [y * setting.scaledSize + x])
                {
                    Coord c      = new Coord(x, y);
                    float height = chunk.chunkData.GetHeightValue(c, setting);
                    float delta  = (height - setting.water) * (1 / (setting.mountain - setting.water));
                    colourMap [y * setting.scaledSize + x] = Color.Lerp(groundMax, groundMin, delta);
                }
            }
        }
        return(TextureGenerator.TextureFromColorMap(colourMap, setting.scaledSize));
    }