Esempio n. 1
0
        //Disables itself if far enough
        public void UpdateVisibilityOrLOD()
        {
            float viewerDistanceFromNearestEdge = Mathf.Sqrt(worldBounds.SqrDistance(viewerPosition));
            bool  shouldBeVisible = viewerDistanceFromNearestEdge <= viewerSightLimit;


            if (!shouldBeVisible && assignedChunkGO != null) //Needed because this method can also be called from callbacks
            {
                disableChunkGO();
            }

            //Going through all the LOD limits (but the last one, because the player cannot see past that one, and choosing the corrent LOD
            if (shouldBeVisible && hasRecievedMapData)
            {
                int lodIndex = 0;

                //Finding the correct LOD...
                for (int i = 0; i < LODLimits.Length - 1; i++)
                {
                    if (viewerDistanceFromNearestEdge > LODLimits[i].distanceUpperBound)
                    {
                        lodIndex = i + 1;
                    }
                    else
                    {
                        break;
                    }
                }

                if (currentLevelOfDetailIndex != lodIndex)
                {
                    LODMesh lodMesh = levelOfDetailMeshes[lodIndex];
                    if (lodMesh.hasRecievedMesh)
                    {
                        //Now that there's a mesh ready, we can request for a gameobject to represent us
                        if (assignedChunkGO == null)
                        {
                            assignedChunkGO = FindObjectOfType <TerrainChunkPooler>().supplyTCObject();
                            setUpChunkGO();
                        }

                        //Setting the mesh
                        currentLevelOfDetailIndex = lodIndex;
                        assignedChunkGO.setMesh(lodMesh.mesh);
                        artifactManager.enableArtifacts(lodMesh.meshLevelOfDetail);
                    }
                    else if (!lodMesh.hasRequestedMesh)
                    {
                        lodMesh.RequestMesh(mapData);
                    }
                    //Otherwise we'll just have to wait and see if data has been recieved yet.
                    //UpdateVisibilityOrLOD will be called from a callback when a mesh is recieved.
                }

                if (shouldBeVisible)
                {
                    terrainChunksVisibleLastFrame.Add(this);
                }
            }
        }
Esempio n. 2
0
    public static void updateChunk(ChunkPos cp, Action <BlockType[, , ], Action <int, int, int, BlockType> > cb)
    {
        TerrainChunkObject chunkObject = chunks[cp];

        BlockType[,,] blocks = chunkObject.Chunk.blocks;
        HashSet <TerrainChunkObject> changed = new HashSet <TerrainChunkObject>();

        cb(blocks, (x, y, z, block) =>
        {
            updateChunkNearbyHelper(cp, changed, x, y, z, block);
            if (x == 1)
            {
                updateChunkNearbyHelper(new ChunkPos(cp.x - TerrainChunk.chunkWidth, cp.z), changed, TerrainChunk.chunkWidth + 1, y, z, block);
            }
            if (z == 1)
            {
                updateChunkNearbyHelper(new ChunkPos(cp.x, cp.z - TerrainChunk.chunkWidth), changed, x, y, TerrainChunk.chunkWidth + 1, block);
            }
            if (x == 1 + TerrainChunk.chunkWidth - 1)
            {
                updateChunkNearbyHelper(new ChunkPos(cp.x + TerrainChunk.chunkWidth, cp.z), changed, 0, y, z, block);
            }
            if (z == 1 + TerrainChunk.chunkWidth - 1)
            {
                updateChunkNearbyHelper(new ChunkPos(cp.x, cp.z + TerrainChunk.chunkWidth), changed, x, y, 0, block);
            }
        });
        foreach (var chunk in changed)
        {
            chunk.UpdateChunk();
        }
    }
Esempio n. 3
0
    public static BlockType getBlock(ChunkPos pos, int x, int y, int z)
    {
        while (x < 0)
        {
            x  += TerrainChunk.chunkWidth;
            pos = new ChunkPos(pos.x - TerrainChunk.chunkWidth, pos.z);
        }
        while (x >= TerrainChunk.chunkWidth)
        {
            x  -= TerrainChunk.chunkWidth;
            pos = new ChunkPos(pos.x + TerrainChunk.chunkWidth, pos.z);
        }
        while (z < 0)
        {
            z  += TerrainChunk.chunkWidth;
            pos = new ChunkPos(pos.x, pos.z - TerrainChunk.chunkWidth);
        }
        while (z >= TerrainChunk.chunkWidth)
        {
            z  -= TerrainChunk.chunkWidth;
            pos = new ChunkPos(pos.x, pos.z + TerrainChunk.chunkWidth);
        }
        if (!chunks.ContainsKey(pos))
        {
            return(BlockType.Air);
        }
        TerrainChunkObject chunk = chunks[pos];

        return(chunk.Chunk.blocks[x + 1, y, z + 1]);
    }
Esempio n. 4
0
    TerrainChunkObject LoadChunk(ChunkPos cp, bool instant)
    {
        if (chunks.ContainsKey(cp))
        {
            return(chunks[cp]);
        }

        TerrainChunk chunk = TerrainChunkGenerator.request(cp, instant);

        if (chunk == null)
        {
            return(null);
        }

        int                xPos        = cp.x;
        int                zPos        = cp.z;
        GameObject         chunkGO     = Instantiate(terrainChunkPrefab, new Vector3(xPos, 0, zPos), Quaternion.identity);
        TerrainChunkObject chunkObject = chunkGO.GetComponent <TerrainChunkObject>();

        chunkObject.transform.parent = transform;
        chunkObject.name             = "Chunk:" + cp;

        chunkObject.BuildMesh(chunk);

        WaterChunk wat = chunkObject.transform.GetComponentInChildren <WaterChunk>();

        wat.SetLocs(chunk.blocks, chunkObject.Chunk);

        wat.BuildMesh();

        chunks.Add(cp, chunkObject);

        return(chunkObject);
    }
Esempio n. 5
0
 public void disableChunkGO()
 {
     if (assignedChunkGO == null)
     {
         return;
     }
     assignedChunkGO.release();
     artifactManager.disableAtifacts();
     assignedChunkGO = null;
 }
            /// <summary>
            /// raise the heightmap of the terrain and rebuild the mesh afterwards
            /// uses the BrushSizeSlider value for it's size
            /// </summary>
            /// <param name="centerX">x position of the center point</param>
            /// <param name="centerY">y position of the center point</param>
            public void RaiseTerrain(int centerX, int centerY, TerrainChunkObject targetChunk)
            {
                int r = TerrainTerraforming.Singleton.brushSize; //brush radius
                float s = TerrainTerraforming.Singleton.brushStrength; //brush strength

                int ox = centerX, oy = centerY; // origin
                int worldSize = WORLD_CHUNK_SIZE * TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE; //total world size
                List<TerrainChunkObject> affectedChunks = new List<TerrainChunkObject>(); //the chunks that will need to be rebuilt

                //raise the heightmap floats
                for (int x = -r; x < r; x++)
                {
                    int height = (int)Mathf.Sqrt(r * r - x * x);

                    for (int y = -height; y < height; y++)
                    {
                        if (x + ox >= 0 && x + ox < worldSize && y + oy >= 0 && y + oy < worldSize)
                        {
                            m_globalheightMap.AddToFloat(x + ox, y + oy, s);
                        }
                    }
                }

                int globalX =  ox; //global x of the circle's center
                int globalY =  oy; //global y of the circle's center

                //calculate affected chunks
                for (int width = 0; width < WORLD_CHUNK_SIZE; width++)
                {
                    for (int length = 0; length < WORLD_CHUNK_SIZE; length++)
                    {
                        int currentGlobalX = m_terrainChunks[width, length].worldX * TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE;
                        int currentGlobalY = m_terrainChunks[width, length].worldY * TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE;

                        if (globalX + r > currentGlobalX && globalY + r > currentGlobalY)
                            if (globalX - r < (currentGlobalX + TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE) && globalY - r < (currentGlobalY + TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE))
                                affectedChunks.Add(m_terrainChunks[width, length]);

                        //reset the highlighing color
                        m_terrainChunks[width, length].GetComponent<Renderer>().material.color = Color.white;
                    }
                }

                //apply changed height floats
                for (int x = 0; x < WORLD_CHUNK_SIZE; x++)
                {
                    for (int y = 0; y < WORLD_CHUNK_SIZE; y++)
                    {

                        m_chunkHeigtmaps[x, y].SetHeightMap(m_globalheightMap.GetPortion(x * TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE,
                            y * TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE, TerrainChunkObject.TERRAIN_CHUNK_TILE_SIZE), m_globalheightMap.highestFloat, m_globalheightMap.lowestFloat, m_globalheightMap.totalStrength);
                    }
                }

                //rebuild affected chunks
                for (int i = 0; i < affectedChunks.Count; i++)
                {
                    affectedChunks[i].RebuildObject();
                    if(renderChunkUpdates)
                        affectedChunks[i].GetComponent<Renderer>().material.color = Color.blue;
                }
            }