Esempio n. 1
0
    // Update is called once per frame
    private void Update()
    {
        DayNightCycle();

        playerChunkCoord = worldData.GetChunkCoord(player.position);

        if (!playerChunkCoord.CompareCoords(playerLastChunkCoord))
        {
            LoadChunks(player.position);
        }

        if (chunksToDraw.Count > 0)
        {
            chunksToDraw.Dequeue().CreateMesh();
        }

        if (!applyingModifications)
        {
            ApplyModifications();
        }

        if (chunksToUpdate.Count > 0)
        {
            UpdateChunks();
        }
    }
Esempio n. 2
0
    private void SetPlayer()
    {
        spawnPoint      = worldData.worldCenter + new Vector3(Random.Range(-8, 8), WorldData.chunkHeight + 50, Random.Range(-8, 8));
        player.position = spawnPoint;

        playerLastChunkCoord = worldData.GetChunkCoord(player.position);
    }
Esempio n. 3
0
    private void Update()
    {
        playerChunkCoord = GetChunkCoordFromVector3(player.position);

        Shader.SetGlobalFloat("GlobalLightLevel", globalLightLevel);
        Camera.main.backgroundColor = Color.Lerp(night, day, globalLightLevel);

        if (!playerChunkCoord.Equals(playerLastChunkCoord))
        {
            CheckViewDistance();
        }

        if (chunksToCreate.Count > 0)
        {
            CreateChunk();
        }

        if (chunksToDraw.Count > 0)
        {
            lock (chunksToDraw)
            {
                if (chunksToDraw.Peek().isEditable)
                {
                    chunksToDraw.Dequeue().CreateMesh();
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.F3))
        {
            debugScreen.SetActive(!debugScreen.activeSelf);
        }
    }
Esempio n. 4
0
    private void GenerateWorld()
    {
        for (int x = (VoxelData.worldSizeInChunks.x / 2) - GameManager.settings.ViewDistanceInChunks; x < (VoxelData.worldSizeInChunks.x / 2) + GameManager.settings.ViewDistanceInChunks; x++)
        {
            for (int z = (VoxelData.worldSizeInChunks.y / 2) - GameManager.settings.ViewDistanceInChunks; z < (VoxelData.worldSizeInChunks.y / 2) + GameManager.settings.ViewDistanceInChunks; z++)
            {
                //for (int x = 0; x < worldSizeInChunks.x; x++)
                //{
                //    for (int z = 0; z < worldSizeInChunks.y; z++)
                //    {

                ChunkCoord newChunkCoord = new ChunkCoord(new int2(x, z));

                chunks[x, z] = new Chunk(newChunkCoord, this, BlockDatabase, EntityManager, GameManager);
                chunksToCreate.Add(newChunkCoord);
            }
        }

        if (player != null)
        {
            player.SpawnPlayer(spawnLocation, BlockDatabase, this, GameManager);
        }

        CheckViewDistance();
    }
Esempio n. 5
0
    void CreateChunk()
    {
        ChunkCoord c = chunksToCreate[0];

        chunksToCreate.RemoveAt(0);
        chunkMap[new ChunkCoord(c.x, c.z)].Init();
    }
Esempio n. 6
0
    private void Update()
    {
        playerChunkCoord = GetChunkCoordFromVector3(player.position);

        if (!playerChunkCoord.Equals(playerLastChunkCoord))
        {
            CheckViewDistance();
        }

        if (modifications.Count > 0 && !applyingModifications)
        {
            StartCoroutine(ApplyModifications());
        }

        if (chunksToCreate.Count > 0)
        {
            CreateChunk();
        }

        if (chunksToUpdate.Count > 0)
        {
            UpdateChunks();
        }

        if (Input.GetKeyDown(KeyCode.F3))
        {
            debugScreen.SetActive(!debugScreen.activeSelf);
        }
    }
Esempio n. 7
0
    private void FixedUpdate()
    {
        playerChunkCoord = GetChunkCoordFromVector3(player.position);

        if (!playerChunkCoord.Equals(playerLastChunkCoord))
        {
            CheckViewDistance();
        }

        if (chunksToCreate.Count > 0)
        {
            CreateChunk();
        }

        if (chunksToDraw.Count > 0)
        {
            if (chunksToDraw.Peek().isEditable&& chunksToDraw.Peek().isVoxelMapPopulated)
            {
                Chunk hold = chunksToDraw.Dequeue();
                hold.CreateMesh();
            }
            else
            {
                Chunk hold = chunksToDraw.Dequeue();
                chunksToDraw.Enqueue(hold);
            }
        }


        // Enable debug
        if (Input.GetKeyDown(KeyCode.F3))
        {
            debugScreen.SetActive(!debugScreen.activeSelf);
        }
    }
Esempio n. 8
0
    void Update()
    {
        if (!playerLastChunkCoord.Equals(GetChunkCoord(player.position)))
        {
            CheckViewDistance();
            playerLastChunkCoord = GetChunkCoord(player.position);
            worldGen.AttemptToSpawnStructures();
        }

        if (chunksToCreate.Count > 0)
        {
            ChunkCoord cc = chunksToCreate[0];
            chunksToCreate.RemoveAt(0);
            activeChunks.Add(cc);
            chunks[cc.x, cc.z].Init();
        }
        if (subchunksToDraw.Count > 0)
        {
            lock (subchunksToDraw) {
                for (int i = 0; i < PerformanceSettings.subchunksToDrawPerFrame; i++)
                {
                    if (subchunksToDraw.Count == 0)
                    {
                        break;
                    }
                    if (GetSubchunk(subchunksToDraw.Peek()).isEditable)
                    {
                        GetSubchunk(subchunksToDraw.Dequeue()).CreateMesh();
                    }
                }
            }
        }
    }
Esempio n. 9
0
 public RenderedHeightmap(ChunkCoord c, float[,] h, float[,,] sm, List<TreeInstance> ti)
 {
     coord 			= c;
     heightmap 		= h;
     splatmap 		= sm;
     treeInstances 	= ti;
 }
Esempio n. 10
0
    IEnumerator ApplyModifications()
    {
        applyingModifications = true;
        int count = 0;

        while (modifications.Count > 0)
        {
            VoxelMod v = modifications.Dequeue();

            ChunkCoord c = GetChunkCoordFromVector3(v.position);

            if (chunks[c.x, c.z] == null)
            {
                chunks[c.x, c.z] = new Chunk(c, this, true);
                activeChunks.Add(c);
            }

            chunks[c.x, c.z].modifications.Enqueue(v);

            if (!chunksToUpdate.Contains(chunks[c.x, c.z]))
            {
                chunksToUpdate.Add(chunks[c.x, c.z]);
            }

            count++;
            if (count > 200)
            {
                count = 0;
                yield return(null);
            }
        }

        applyingModifications = false;
    }
Esempio n. 11
0
    public SubchunkCoord GetSubchunkCoord(Vector3 globalPos)
    {
        ChunkCoord superChunk    = GetChunkCoord(globalPos);
        byte       subchunkIndex = Subchunk.GetSubchunkIndex(Mathf.FloorToInt(globalPos.y));

        return(new SubchunkCoord(superChunk, subchunkIndex));
    }
Esempio n. 12
0
 public AnvilChunk(AnvilChunkManager manager, ChunkCoord coord)
 {
     _coord        = coord;
     _manager      = manager;
     _entities     = new ChunkEntityCollection(new TagList());
     _tileEntities = new Dictionary <BlockPos, TagCompound>();
 }
Esempio n. 13
0
    void ApplyModifications()
    {
        applyingModifications = true;

        while (modifications.Count > 0)
        {
            Queue <CubeMod> queue = modifications.Dequeue();

            while (queue.Count > 0)
            {
                CubeMod v = queue.Dequeue();

                ChunkCoord c = GetChunkCoordFromVector3(v.position);

                if (chunks[c.x, c.z] == null)
                {
                    chunks[c.x, c.z] = new Chunk(c, this, true);
                    activeChunks.Add(c);
                }

                chunks[c.x, c.z].modifications.Enqueue(v);

                if (!chunksToUpdate.Contains(chunks[c.x, c.z]))
                {
                    chunksToUpdate.Add(chunks[c.x, c.z]);
                }
            }
        }

        applyingModifications = false;
    }
Esempio n. 14
0
    public Chunk(ChunkCoord _coord)
    {
        coord = _coord;

        chunkObject  = new GameObject();
        meshFilter   = chunkObject.AddComponent <MeshFilter>();
        meshRenderer = chunkObject.AddComponent <MeshRenderer>();

        materials[0]           = World.Instance.material;
        materials[1]           = World.Instance.transparentMaterial;
        meshRenderer.materials = materials;

        chunkObject.transform.SetParent(World.Instance.transform);
        chunkObject.transform.position = new Vector3(coord.x * VoxelData.ChunkWidth, 0f, coord.z * VoxelData.ChunkWidth);
        chunkObject.name = "Chunk " + coord.x + ", " + coord.z;
        position         = chunkObject.transform.position;

        chunkData       = World.Instance.worldData.RequestChunk(new Vector2Int((int)position.x, (int)position.z), true);
        chunkData.chunk = this;

        World.Instance.AddChunkToUpdate(this);

        if (World.Instance.settings.enableAnimatedChunks)
        {
            chunkObject.AddComponent <ChunkLoadAnimation>();
        }
    }
Esempio n. 15
0
    void CreateChunk()
    {
        ChunkCoord c = chunksToCreate[0];

        chunksToCreate.RemoveAt(0);
        chunks[c.x, c.z].init();
    }
Esempio n. 16
0
    private void CreateChunk()
    {
        ChunkCoord chunk = chunksToCreate[0];

        chunksToCreate.RemoveAt(0);
        chunks[chunk.x, chunk.z].CreateChunk();
    }
Esempio n. 17
0
    public void AttemptToSpawnStructures()
    {
        List <int> chunksToRemoveFromList = new List <int>();

        for (int i = 0; i < chunksToSpawnStructures.Count; i++)
        {
            ChunkCoord cc = chunksToSpawnStructures[i];
            //Checks to see if chunk we are attempting spawning on is in the view distance. If not, skip
            if (Mathf.Abs(world.playerLastChunkCoord.x - cc.x) > VoxelData.ViewDistanceInChunks &&
                Mathf.Abs(world.playerLastChunkCoord.z - cc.z) > VoxelData.ViewDistanceInChunks)
            {
                continue;
            }
            //Check neighbours to see if exist and voxels are populated
            if (AreNeighboursPopulated(cc))
            {
                world.GetChunk(cc).PopulateSpawnableStructures();
                chunksToRemoveFromList.Add(i);
            }
        }
        // Goes in reverse order so as to not disturb index. Removes chunks that have been populated
        for (int j = chunksToRemoveFromList.Count - 1; j >= 0; j--)
        {
            chunksToSpawnStructures.RemoveAt(j);
        }
    }
    public void invalidateChunkAt(ref ChunkCoord neighbourNeedRefresh, bool Immediate)
    {
        lock (chunkDict)
        {
            chunkDict.TryGetValue(neighbourNeedRefresh, out neighbourNeedRefresh.chunk);
        }
        Chunk chunk = neighbourNeedRefresh.chunk;

        if (chunk != null)
        {
            if (Immediate)
            {
                chunk.PullChunkDataAndUpdateChunk();
                neighbourNeedRefresh.chunk = null;
            }
            else
            {
                lock (threadingChunks) {
                    //   //ChunkUpdateThread.Interrupt();
                    //   chunk.waitingForNewLoad = false;
                    //   threadingChunks.Insert(0, neighbourNeedRefresh);
                    //   //ChunkUpdateThread.Start();
                    new Thread(new ThreadStart(neighbourNeedRefresh.chunk.PullChunkDataAndUpdateChunk_)).Start();
                }
                //todo
            }
        }
        neighbourNeedRefresh = null;
    }
Esempio n. 19
0
 public void SetChunk(Chunk chunk, ChunkCoord cc)
 {
     if (isChunkInWorld(cc))
     {
         chunks[cc.x, cc.z] = chunk;
     }
 }
Esempio n. 20
0
    private void Start()
    {
        Debug.Log("Generating new world using seed: " + VoxelData.seed);

        worldData = SaveSystem.LoadWorld("New World");

        //string jsonExport = JsonUtility.ToJson(settings);
        //Debug.Log(jsonExport);

        //File.WriteAllText(Application.dataPath + "/settings.cfg", jsonExport);

        string jsonImport = File.ReadAllText(Application.dataPath + "/settings.cfg");

        settings = JsonUtility.FromJson <Settings>(jsonImport);

        Random.InitState(VoxelData.seed);

        Shader.SetGlobalFloat("minGlobalLightLevel", VoxelData.minLightLevel);
        Shader.SetGlobalFloat("maxGlobalLightLevel", VoxelData.maxLightLevel);

        if (settings.enableThreading)
        {
            ChunkUpdateThread = new Thread(new ThreadStart(ThreadedUpdate));
            ChunkUpdateThread.Start();
        }

        SetGlobalLightValue();
        spawnPosition = new Vector3((VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2f, VoxelData.ChunkHeight - 50f, (VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2f);
        GenerateWorld();
        playerLastChunkCoord = GetChunkCoordFromVector3(player.position);
    }
Esempio n. 21
0
    private void Update()
    {
        playerChunkCoord = GetChunkCoordFromVector3(player.Position);

        // Only update the chunks if the player has moved from the chunk they were previously on
        if (!playerChunkCoord.Equals(playerLastChunkCoord))
        {
            CheckViewDistance();
        }

        if (chunksToCreate.Count > 0 && !isCreatingChunks)
        {
            StartCoroutine(CreateChunks());
        }

        if (!GameManager.settings.enableThreading)
        {
            if (chunksToUpdate.Count > 0)
            {
                UpdateChunks();
            }
        }

        if (chunksToDraw.Count > 0)
        {
            if (chunksToDraw.Peek().IsEditable)
            {
                chunksToDraw.Dequeue().CreateMesh(BlockDatabase.blockMaterialAtlas);
            }
        }
    }
Esempio n. 22
0
    void ApplyModifications()
    {
        applyingModifications = true;

        while (modifications.Count > 0)
        {
            Queue <VoxelMod> queue = modifications.Dequeue();

            while (queue.Count > 0)
            {
                VoxelMod v = queue.Dequeue();

                ChunkCoord c             = GetChunkCoordFromVector3(v.position);
                ChunkCoord newChunkCoord = new ChunkCoord(c.x, c.z);

                if (!chunkMap.ContainsKey(newChunkCoord))
                {
                    chunkMap.TryAdd(newChunkCoord, new Chunk(c, this));
                    chunksToCreate.Add(c);
                }

                chunkMap[newChunkCoord].modifications.Enqueue(v);
            }
        }
        applyingModifications = false;
    }
Esempio n. 23
0
    //from project settings the fixed update is set to 0.05 seconds ie. 20 tics per second
    //generating  1 chunk from queue every 0.05 seconds should offload some work when processing giant squares of new chunks at once
    //after trying it seems to not have impact on basic physics in game
    //if weird things wiith physics will occur probably switch to courutine

    private void FixedUpdate()
    {
        currentPlayerPosInChunk = ChunkCalculations.CalculateChunkFromWorldPos(player.position);
        if (currentChunkPos.posX != currentPlayerPosInChunk.posX || currentChunkPos.posZ != currentPlayerPosInChunk.posZ)
        {
            for (int i = -5; i <= 5; i++)
            {
                for (int j = -5; j <= 5; j++)
                {
                    if (!VoxelData.chunkDictionary.ContainsKey(new ChunkCoord((int)(player.position.x / 15 + i), (int)(player.position.z / 15 + j))))
                    {
                        int x = (int)(player.position.x / 15 + i);
                        int z = (int)(player.position.z / 15 + j);
                        if (toGenerateUniques.Add(new ChunkCoord(x, z)))
                        {
                            toGenerate.Enqueue(new ChunkCoord(x, z));
                        }
                    }
                }
            }
            currentChunkPos = currentPlayerPosInChunk;
        }
        if (toGenerate.Count > 0)
        {
            toGenerateUniques.Remove(toGenerate.Peek());
            SpawnChunk(toGenerate.Dequeue());
        }
    }
    private void Start()
    {
        worldData = SaveSystem.LoadWorld("Testing");

        string jsonImport = File.ReadAllText(Application.dataPath + "/settings.cfg");

        settings = JsonUtility.FromJson <Settings>(jsonImport);

        Random.InitState(VoxelData.seed);

        Shader.SetGlobalFloat("minGlobalLightLevel", VoxelData.minLightLevel);
        Shader.SetGlobalFloat("maxGlobalLightLevel", VoxelData.maxLightLevel);

        SetGlobalLightValue();
        spawnPosition = new Vector3(VoxelData.WorldCentre, VoxelData.ChunkHeight - 50f, VoxelData.WorldCentre);
        LoadWorld();
        //ApplyModifications();
        GenerateWorld();
        playerLastChunkCoord = GetChunkCoordFromVector3(player.position);

        if (settings.enableThreading)
        {
            ChunkUpdateThread = new Thread(new ThreadStart(ThreadedUpdate));
            ChunkUpdateThread.Start();
        }
    }
    public void CheckViewDistance(int viewDistance, ChunkCoord coord)
    {
        for (int i = 0; i < activeChunks.Count; i++)
        {
            ChunkCoord c = activeChunks[i];
            if ((c.x < coord.x - viewDistance || c.x > coord.x + viewDistance) || (c.z < coord.z - viewDistance || c.z > coord.z + viewDistance))
            {
                GetChunkFromChunks(c).IsActive = false;
                activeChunks.RemoveAt(i);
                i--;
            }
        }

        for (int x = coord.x - viewDistance; x <= coord.x + viewDistance; x++)
        {
            for (int z = coord.z - viewDistance; z <= coord.z + viewDistance; z++)
            {
                ChunkCoord checkCoord = new ChunkCoord(x, z);

                Chunk current = GetChunkFromChunks(checkCoord);

                if (current == null)
                {
                    QueueChunkForCreation(checkCoord);
                }
                else if (!current.IsActive)
                {
                    current.IsActive = true;
                    activeChunks.Add(checkCoord);
                }
            }
        }
    }
 private void RepositionChunk(Chunk chunkToReposition, ChunkCoord coord)
 {
     chunkToReposition.waitingForNewLoad = true;
     //ChunkCoord from = new ChunkCoord(chunkToReposition.coord);
     lock (chunkDict)
     {
         chunkDict.Remove(chunkToReposition.coord);
         chunkDict.Add(coord, chunkToReposition);
         ChunkData data = chunkToReposition.getFilledData();
         if (data != null) // 需要归还数据 回收
         {
             lock (worldData)
             {
                 if (!worldData.PeripheralChunkDataDict.ContainsKey(chunkToReposition.coord))
                 {
                     worldData.PeripheralChunkDataDict.Add(chunkToReposition.coord, data);
                     worldData.PeripheralChunkDatas.Add(data);
                 }
             }
         }
     }
     chunkToReposition.Reposition(coord);
     //Debug.Log(string.Format("RepositionChunk From::{0}, {1} To::{2}, {3}", from.x, from.z, coord.x, coord.z));
     lock (threadingChunks) {
         //threadingChunks.Insert(0, coord);
         threadingChunks.Remove(coord);
         threadingChunks.Add(coord);
     }
     //BoxDebug.DrawBox(new Vector3(coord.x*VoxelData.TileWidthUU, 40, coord.z*VoxelData.TileWidthUU), new Vector3(VoxelData.TileWidthUU, 10, VoxelData.TileWidthUU), Color.green, 6);
 }
Esempio n. 27
0
    /**
     * Render the chunk at the position chunkCenter.
     */
    protected void loadChunk(Vector2 chunkCenter)
    {
        Chunk      chunk;
        int        details    = getDetails(chunkCenter);
        ChunkCoord chunkCoord = getChunkCoord(chunkCenter);

        if (details == 0)
        {
            return;
        }

        //if the chunk does not exist, create the chunk
        if (!chunks.TryGetValue(chunkCoord, out chunk))
        {
            chunk = new Chunk(chunkCenter, mapGenerator, materail);
            chunks.Add(chunkCoord, chunk);
        }

        //check the levelOfDetail of the chunks that are connected to this chunk
        bool lowResTop    = getDetails(new Vector2(chunkCenter.x, chunkCenter.y + Chunk.size * h_sqrt_3)) > details;
        bool lowResBottom = getDetails(new Vector2(chunkCenter.x, chunkCenter.y - Chunk.size * h_sqrt_3)) > details;
        bool lowResLeft   = getDetails(new Vector2(chunkCenter.x - Chunk.size, chunkCenter.y)) > details;
        bool lowResRight  = getDetails(new Vector2(chunkCenter.x + Chunk.size, chunkCenter.y)) > details;

        chunk.visible(details, lowResTop, lowResRight, lowResBottom, lowResLeft);
    }
Esempio n. 28
0
 //generates world from player position when instance of script is created
 private void Start()
 {
     spawnPosition = new Vector3((VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2f, VoxelData.ChunkHeight - 50f, (VoxelData.WorldSizeInChunks * VoxelData.ChunkWidth) / 2f);
     Random.InitState(seed);
     GenerateWorld();
     playerLastChunkCoord = GetChunkCoordFromVector3(player.transform.position);
 }
Esempio n. 29
0
    void ApplyModifications()
    {
        applyingModifications = true;

        while (modifications.Count > 0)
        {
            Queue <VoxelMod> queue = modifications.Dequeue();

            while (queue.Count > 0)
            {
                VoxelMod v = queue.Dequeue();

                ChunkCoord c = GetChunkCoordFromVector3(v.position);

                if (chunks[c.x, c.z] == null)
                {
                    chunks[c.x, c.z] = new Chunk(c, this);
                    chunksToCreate.Add(c);
                }

                chunks[c.x, c.z].modifications.Enqueue(v);
            }
        }

        applyingModifications = false;
    }
Esempio n. 30
0
 private void Update()
 {
     playerChunkCoord = GetChunkCoordFromVector3(player.position);
     if (!playerChunkCoord.Equals(playerLastChunkCoord))
     {
         CheckViewDistance();
     }
     if (chunksToDraw.Count > 0)
     {
         chunksToDraw.Dequeue().CreateMesh();
     }
     if (Input.GetKeyDown(KeyCode.F3))
     {
         DebugScreen.SetActive(!DebugScreen.activeSelf);
     }
     if (!settings.EnableThreading)
     {
         if (!applyingModifications)
         {
             ApplyModifications();
         }
         if (chunksToUpdate.Count > 0)
         {
             UpdateChunks();
         }
     }
     if (Input.GetKeyDown(KeyCode.F5))
     {
         SaveSystem.SaveWorld(worldData);
     }
 }
Esempio n. 31
0
    private void Start()
    {
        Debug.Log($"Seed id: {VoxelData.seed}");
        worldData = SaveSystem.LoadWorld("Prototype");
        ImportSettings();
        UnityEngine.Random.InitState(VoxelData.seed);
        Shader.SetGlobalFloat("MinGlobalLightLevel", VoxelData.minGlobalLightLevel);
        Shader.SetGlobalFloat("MaxGlobalLightLevel", VoxelData.maxGlobalLightLevel);
        LoadWorld();
        SetGlobalLightValue();
        spawnPosition   = new Vector3(VoxelData.WorldCenter, VoxelData.ChunkHeight - 50, VoxelData.WorldCenter);
        player.position = spawnPosition;
        CheckViewDistance();
        playerChunkCoord     = GetChunkCoordFromVector3(player.position);
        playerLastChunkCoord = playerChunkCoord;

        if (settings.EnableThreading)
        {
            chunkUpdateThread = new Thread(new ThreadStart(ThreadedUpdate));
            chunkUpdateThread.Start();
        }
        else
        {
        }
    }
Esempio n. 32
0
 internal FluidType GetLiquidType(ChunkCoord chunkCoord)
 {
     return LiquidTypes[chunkCoord.ChunkX, chunkCoord.ChunkY];
 }
Esempio n. 33
0
	void stitchTerrain(TerrainData tData, ChunkCoord c) {
		TerrainData left   = (TerrainData)chunks[new ChunkCoord(c.x - 1, c.z)];
		TerrainData right  = (TerrainData)chunks[new ChunkCoord(c.x + 1, c.z)];
		TerrainData top    = (TerrainData)chunks[new ChunkCoord(c.x,     c.z - 1)];
		TerrainData bottom = (TerrainData)chunks[new ChunkCoord(c.x,     c.z + 1)];

		if (left != null) {
			var seam = left.GetHeights(chunkResolution - 1, 0, 1, chunkResolution);
			tData.SetHeights(0, 0, seam);
		}
		if (right != null) {
			var seam = right.GetHeights(0, 0, 1, chunkResolution);
			tData.SetHeights(chunkResolution - 1, 0, seam);
		}
		if (top != null) {
			var seam = top.GetHeights(0, chunkResolution-1, chunkResolution, 1);
			tData.SetHeights(0, 0, seam);
		}
		if (bottom != null) {
			var seam = bottom.GetHeights(0, 0, chunkResolution, 1);
			tData.SetHeights(0, chunkResolution - 1, seam);
		}
	}
Esempio n. 34
0
	void ensureChunk(ChunkCoord c, bool async) {
		if (outstanding < threads) {
			if (!chunks.Contains(c)) {
				chunks.Add(c, null);
				if (async) {
					outstanding += 1;
					this.StartCoroutineAsync(generateHeightmapAsync(c));
				} else {
					generateHeightmapSync(c);
				}
			}
		}
	}
Esempio n. 35
0
	IEnumerator generateHeightmapAsync(ChunkCoord c) {
		// This is called on a background thread.  It needs to build the
		// heightmap array (and possibly some other stuff) and push it onto the
		// queue when ready.

		generateHeightmapSync(c);

		yield return Ninja.JumpToUnity;

		print("Outstanding: " + outstanding);
		outstanding -= 1;

		yield return Ninja.JumpBack;
	}
Esempio n. 36
0
	void generateHeightmapSync(ChunkCoord c) {
		int heightmapResolution = chunkResolution + (2 * fringeSize);
		float[,] heightmap = new float[heightmapResolution, heightmapResolution];

		noiseHeightmap(c, heightmap);
		erodeHeightmap(c, heightmap);

		heightmap = extractChunk(heightmap);

		var splatmap = textureHeightmap(heightmap);

		// Done, push it into the queue so the main thread can process it into
		// a terrain object.
		heightmapQueue.Enqueue(new RenderedHeightmap(c, heightmap, splatmap));
	}
Esempio n. 37
0
        internal float GetInterpolatedHeight(ChunkCoord chunkCoord, PointX2D coord, HeightMapFraction heightMapFraction)
        {
            // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
            // +--------------> X
            // | h1--------h2   Coordinates are:
            // | |    |    |     h1 0,0
            // | |  1 |  2 |     h2 0,1
            // | |----h5---|     h3 1,0
            // | |  3 |  4 |     h4 1,1
            // | |    |    |     h5 1/2,1/2
            // | h3--------h4
            // V Y
            if (HeightMaps == null) return float.NaN;

            var heightMap = HeightMaps[chunkCoord.ChunkX, chunkCoord.ChunkY];
            if (heightMap == null) return float.NaN;

            var medianHeight = HalfUtils.Unpack(heightMap.MedianHeight);
            if (heightMap.IsFlat) return medianHeight;

            // Fixme:  Indexing is backwards.
            var heightX = (coord.Y == TerrainConstants.UnitsPerChunkSide)
                              ? (TerrainConstants.UnitsPerChunkSide - 1)
                              : coord.Y;
            var heightY = (coord.X == TerrainConstants.UnitsPerChunkSide)
                              ? (TerrainConstants.UnitsPerChunkSide - 1)
                              : coord.X;

            
            // Determine what quad we're in
            var xf = heightMapFraction.FractionX;
            var yf = heightMapFraction.FractionY;

            float topLeft, topRight, bottomLeft, bottomRight;
            if (xf < 0.5f)
            {
                if (yf < 0.5)
                {
                    // Calc the #1 quad
                    // +--------------> X
                    // | h1--------h2    Coordinates are:
                    // | |    |    |      h1 0,0
                    // | |  1 |    |      h2 0,1
                    // | |----h5---|      h3 1,0
                    // | |    |    |      h4 1,1
                    // | |    |    |      h5 1/2,1/2
                    // | h3--------h4
                    // V Y
                    var packed1 = heightMap.OuterHeightDiff[heightX, heightY];
                    var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1];
                    var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY];
                    var packed5 = heightMap.InnerHeightDiff[heightX, heightY];

                    var h1 = HalfUtils.Unpack(packed1);
                    var h2 = HalfUtils.Unpack(packed2);
                    var h3 = HalfUtils.Unpack(packed3);
                    var h5 = HalfUtils.Unpack(packed5);

                    topLeft = h1;
                    topRight = (h1 + h2)/2.0f;
                    bottomLeft = (h1 + h3)/2.0f;
                    bottomRight = h5;
                }
                else
                {
                    // Calc the #3 quad
                    // +--------------> X
                    // | h1--------h2    Coordinates are:
                    // | |    |    |      h1 0,0
                    // | |    |    |      h2 0,1
                    // | |----h5---|      h3 1,0
                    // | |  3 |    |      h4 1,1
                    // | |    |    |      h5 1/2,1/2
                    // | h3--------h4
                    // V Y
                    var packed1 = heightMap.OuterHeightDiff[heightX, heightY];
                    var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY];
                    var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1];
                    var packed5 = heightMap.InnerHeightDiff[heightX, heightY];

                    var h1 = HalfUtils.Unpack(packed1);
                    var h3 = HalfUtils.Unpack(packed3);
                    var h4 = HalfUtils.Unpack(packed4);
                    var h5 = HalfUtils.Unpack(packed5);

                    topLeft = (h1 + h3) / 2.0f;
                    topRight = h5;
                    bottomLeft = h3;
                    bottomRight = (h3 + h4) / 2.0f;

                    yf -= 0.5f;
                }
            }
            else
            {
                if (yf < 0.5)
                {
                    // Calc the #2 quad
                    // +--------------> X
                    // | h1--------h2    Coordinates are:
                    // | |    |    |      h1 0,0
                    // | |    |  2 |      h2 0,1
                    // | |----h5---|      h3 1,0
                    // | |    |    |      h4 1,1
                    // | |    |    |      h5 1/2,1/2
                    // | h3--------h4
                    // V Y
                    var packed1 = heightMap.OuterHeightDiff[heightX, heightY];
                    var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1];
                    var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1];
                    var packed5 = heightMap.InnerHeightDiff[heightX, heightY];

                    var h1 = HalfUtils.Unpack(packed1);
                    var h2 = HalfUtils.Unpack(packed2);
                    var h4 = HalfUtils.Unpack(packed4);
                    var h5 = HalfUtils.Unpack(packed5);

                    topLeft = (h1 + h2) / 2.0f;
                    topRight = h2;
                    bottomLeft = h5;
                    bottomRight = (h2 + h4) / 2.0f;

                    xf -= 0.5f;
                }
                else
                {
                    // Calc the #4 quad
                    // +--------------> X
                    // | h1--------h2    Coordinates are:
                    // | |    |    |      h1 0,0
                    // | |    |    |      h2 0,1
                    // | |----h5---|      h3 1,0
                    // | |    |  4 |      h4 1,1
                    // | |    |    |      h5 1/2,1/2
                    // | h3--------h4
                    // V Y
                    var packed2 = heightMap.OuterHeightDiff[heightX, heightY + 1];
                    var packed3 = heightMap.OuterHeightDiff[heightX + 1, heightY];
                    var packed4 = heightMap.OuterHeightDiff[heightX + 1, heightY + 1];
                    var packed5 = heightMap.InnerHeightDiff[heightX, heightY];

                    var h2 = HalfUtils.Unpack(packed2);
                    var h3 = HalfUtils.Unpack(packed3);
                    var h4 = HalfUtils.Unpack(packed4);
                    var h5 = HalfUtils.Unpack(packed5);

                    topLeft = h5;
                    topRight = (h2 + h4) / 2.0f;
                    bottomLeft = (h3 + h4) / 2.0f;
                    bottomRight = h4;

                    xf -= 0.5f;
                    yf -= 0.5f;
                }
            }

            //var heightDiff = InterpolateTriangle(ref vec1, ref vec2, ref vec3, heightMapFraction);
            var heightDiff = BilinearInterpolate(ref topLeft, ref topRight, ref bottomLeft, ref bottomRight, ref xf,
                                                 ref yf);
            return medianHeight + heightDiff;
        }
Esempio n. 38
0
	public RenderedHeightmap(ChunkCoord c, float[,] h, float[,,] sm) {
		coord = c;
		heightmap = h;
		splatmap = sm;
	}
Esempio n. 39
0
        internal void DumpChunk(ChunkCoord chunkCoord)
        {
            if (HeightMaps == null) return;

            var heightMap = HeightMaps[chunkCoord.ChunkX, chunkCoord.ChunkY];
            if (heightMap == null) return;

            var medianHeight = HalfUtils.Unpack(heightMap.MedianHeight);
            
            var fileName = String.Format("Chunk_{0}_{1}.txt", chunkCoord.ChunkX, chunkCoord.ChunkY);
            var filePath = Path.Combine("C:\\Users\\Nate\\Desktop", fileName);
            var writer = new StreamWriter(filePath);

            writer.WriteLine(String.Format("MedianHeight: {0}", medianHeight));
            if (heightMap.IsFlat)
            {
                writer.Close();
                return;
            }
            writer.Write(writer.NewLine);

            for (var row = 0; row < 9; row++)
            {
                for (var col = 0; col < 9; col++)
                {
                    var packed = heightMap.OuterHeightDiff[row, col];
                    var unpacked = HalfUtils.Unpack(packed);
                    var value = Math.Round(unpacked, 2);
                    if (value >= 0) writer.Write(" ");
                    writer.Write(String.Format("{0:00.00}    ", value));
                }
                writer.Write(writer.NewLine);
                writer.Write(writer.NewLine);

                // write 8 floats
                if (row < 8)
                {
                    writer.Write("    ");
                    for (var col = 0; col < 8; col++)
                    {
                        var packed = heightMap.InnerHeightDiff[row, col];
                        var unpacked = HalfUtils.Unpack(packed);
                        var value = Math.Round(unpacked, 2);
                        if (value >= 0) writer.Write(" ");
                        writer.Write(String.Format("{0:00.00}    ", value));
                    }
                    writer.Write(writer.NewLine);
                    writer.Write(writer.NewLine);
                }
            }

            writer.Close();
        }
Esempio n. 40
0
    void noiseHeightmap(ChunkCoord c, float[,] heightmap)
    {
        int width = heightmap.GetLength(0);
        int height = heightmap.GetLength(1);

        for (int z = 0; z < height; z++) {
            for (int x = 0; x < width; x++) {
                heightmap[z, x] = noise.Get(
                        x + getWorldOX(c),
                        z + getWorldOZ(c));
            }
        }
    }
Esempio n. 41
0
        internal float GetLiquidHeight(ChunkCoord chunkCoord, PointX2D pointX2D)
        {
            if (!LiquidProfile[chunkCoord.ChunkX, chunkCoord.ChunkY])
                return float.MinValue;

            var heightMap = HeightMaps[chunkCoord.ChunkX, chunkCoord.ChunkY];
            var liquidHeights = heightMap.LiquidHeight;

            return (liquidHeights == null)
                       ? float.MinValue
                       : liquidHeights[pointX2D.X, pointX2D.Y];
        }
Esempio n. 42
0
	void erodeHeightmap(ChunkCoord c, float[,] heightmap) {
		reverseThermalEroder.Erode(heightmap);
		hydraulicEroder.Erode(heightmap);
		thermalEroder.Erode(heightmap);
	}
Esempio n. 43
0
    float[,,] textureHeightmap(ChunkCoord c, float[,] heightmap, int[,] randomArray)
    {
        // determain the mix of textures 1, 2, 3 and 4 to use
        var splatmap = new float[
            heightmap.GetLength(0),
            heightmap.GetLength(1),
            diffuses.Length];

        splatmap = texturer.Texture(
                heightmap, splatmap, randomArray, getWorldOX(c), getWorldOZ(c));

        return splatmap;
    }
Esempio n. 44
0
 int getWorldOX(ChunkCoord c)
 {
     return (c.x * chunkResolution - c.x - fringeSize);
 }
Esempio n. 45
0
 int getWorldOZ(ChunkCoord c)
 {
     return (c.z * chunkResolution - c.z - fringeSize);
 }
Esempio n. 46
0
	void noiseHeightmap(ChunkCoord c, float[,] heightmap) {
		int ox = c.x * chunkResolution - c.x - fringeSize;
		int oz = c.z * chunkResolution - c.z - fringeSize;

		int width = heightmap.GetLength(0);
		int height = heightmap.GetLength(1);

		for (int z = 0; z < height; z++) {
			for (int x = 0; x < width; x++) {
				heightmap[z, x] = noise.Get(ox + x, oz + z);
			}
		}
	}
Esempio n. 47
0
    void ensureChunk(ChunkCoord c, bool async)
    {
        if (outstanding < threads) {
            if (!chunks.Contains(c)) {
                chunks.Add(c, null);

                // RandomRangeInt can only be called from the main thread.
                // So we need to pass an array of random numbers to the child thread
                int heightmapResolution = chunkResolution + (2 * fringeSize);
                var randomArray = new int[heightmapResolution, heightmapResolution];
                for (var i = 0; i < heightmapResolution; i++) {
                    for (var j = 0; j < heightmapResolution; j++) {
                        randomArray[i,j] = UnityEngine.Random.Range(0, 100000);
                    }
                }

                if (async) {
                    outstanding += 1;
                    this.StartCoroutineAsync(generateHeightmapAsync(c, randomArray));
                } else {
                    generateHeightmapSync(c, randomArray);
                }
            }
        }
    }