예제 #1
0
    public void StartUp(VoxelMap map, WorldScriptableObject worldObject)
    {
        voxelMesh     = FindObjectOfType <VoxelMesh>();
        terrainNoise  = FindObjectOfType <TerrainNoise>();
        terrainMap    = FindObjectOfType <TerrainMap>();
        chunkCollider = FindObjectOfType <ChunkCollider>();

        recycleableChunks     = map.recycleableChunks;
        regionResolution      = map.regionResolution;
        chunkResolution       = map.chunkResolution;
        voxelResolution       = map.voxelResolution;
        viewDistance          = map.viewDistance;
        chunks                = map.chunks;
        existingChunks        = map.existingChunks;
        useVoxelReferences    = map.useVoxelReferences;
        colliderRadius        = map.colliderRadius;
        useColliders          = map.useColliders;
        player                = map.player;
        chunkSaveLoadManager  = map.chunkSaveLoadManager;
        worldScriptableObject = worldObject;

        playerRb = player.GetComponent <Rigidbody2D>();

        terrainNoise.seed = worldScriptableObject.seed;
        terrainNoise.Startup(voxelResolution, chunkResolution);
        voxelMesh.Startup(voxelResolution, chunkResolution, viewDistance, useColliders, colliderRadius);

        InvokeRepeating(nameof(UpdateMap), 0.0f, terrainMap.updateInterval);
    }
    //Function to generate the noise map
    MapData GenerateMapData(Vector2 centre)
    {
        float[,] noiseMap = TerrainNoise.GenerateNoiseMap(mapChunkSize + 2, mapChunkSize + 2, seed, noiseScale, octaves, persistance, lacunarity, centre + offset, normalizeMode);

        //Generating colored map
        Color[] colorMap = new Color[mapChunkSize * mapChunkSize];             //Array to save all colors used
        for (int y = 0; y < mapChunkSize; y++)
        {
            for (int x = 0; x < mapChunkSize; x++)
            {
                if (useIslandGenerator)
                {
                    noiseMap[x, y] = Mathf.Clamp01(noiseMap[x, y] - islandGenMap[x, y]);
                }
                float currentHeight = noiseMap[x, y];
                for (int i = 0; i < regions.Length; i++)         //Loop to check which region the current height value falls into
                {
                    if (currentHeight >= regions[i].height)
                    {
                        colorMap[y * mapChunkSize + x] = regions[i].color;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        return(new MapData(noiseMap, colorMap));
    }
예제 #3
0
        public OverworldTerrain(OverworldTerrainSettings ots, bool isUnitTest = false)
        {
            settings = ots;

            ocean     = new OceanTerrain(ots);
            plains    = new PlainsTerrain(ots);
            hills     = new HillsTerrain(ots);
            badlands  = new BadlandsTerrain(ots);
            mountains = new MountainsTerrain(ots);
            rivers    = new RiverTerrain(ots);

            humidity    = new HumidityNoise(ots);
            temperature = new TemperatureNoise(ots);
            terrain     = new TerrainNoise(ots);

            cave = new CavesCarver(ots);

            // Scale Point multiplies input values by the scaling factors.
            // Used to stretch or shrink the terrain horizontally.
            var scaled = GetScaledModuleOutput(MergedLandOceanRivers());
            //var scaled = GetScaledModuleOutput(LandOceanSelector());
            //var scaled = GetScaledModuleOutput(temperature.RiverSelector);

            // Scale bias scales the verical output (usually -1.0 to +1.0) to
            // Minecraft values. If MinElev is 40 (leaving room for caves under oceans)
            // and MaxElev is 168, a value of -1 becomes 40, and a value of 1 becomes 168.
            var biased = new ScaleBias
            {
                Scale   = (settings.MaxElev - settings.MinElev) / 2.0,
                Bias    = settings.MinElev + ((settings.MaxElev - settings.MinElev) / 2.0) - 44,
                Source0 = scaled
            };

            Result = isUnitTest ? scaled : biased;
        }
예제 #4
0
 private void Awake()
 {
     rb             = GetComponent <Rigidbody2D>();
     boxCollider    = GetComponent <Collider2D>();
     bodyController = transform.Find("BodyController");
     terrainNoise   = FindObjectOfType <TerrainNoise>();
 }
예제 #5
0
        public IEnumerator TerrainNoiseOutputsNotFlat(NoiseSource noiseSource)
        {
            TerrainNoise terrainNoise = makeTerrainNoise(noiseSource);

            float[,] heightMap = new float[3, 3];
            terrainNoise.FillHeightMapNoise(0, 0, heightMap);
            Assert.AreNotEqual(heightMap[0, 0], heightMap[0, 2]);
            Assert.AreNotEqual(heightMap[0, 0], heightMap[2, 0]);
            yield return(null);
        }
예제 #6
0
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        TerrainNoise noiser = (TerrainNoise)target;

        if (GUILayout.Button("Run"))
        {
            noiser.Run();
        }
    }
예제 #7
0
    private void Start()
    {
        mapMaterial  = map.GetComponent <Image>().material;
        player       = FindObjectOfType <PlayerController>().transform;
        terrainNoise = FindObjectOfType <TerrainNoise>();
        voxelMap     = FindObjectOfType <VoxelMap>();

        RefreshColors();

        NewTexture();
    }
예제 #8
0
    public TerrainData GenerateTerrainData(TerrainSettings terrainSettings, Vector2Int size, Vector2 offset)
    {
        int width  = size.x;
        int height = size.y;

        AnimationCurve heightCurve = new AnimationCurve(terrainSettings.heightCurve.keys);

        float[,] heightMap = TerrainNoise.GenerateNoiseMap(width, height, terrainSettings.noiseSeed, terrainSettings.noiseScale, terrainSettings.octaves, terrainSettings.persistance, terrainSettings.lacunarity, offset, terrainSettings.normalizeMode);
        Color[]  colorMap = CreateColorMap(heightMap, terrainSettings.regions);
        MeshData meshData = MeshGenerator.GenerateMesh(heightMap, terrainSettings.heightScale, heightCurve);

        return(new TerrainData(heightMap, colorMap, meshData, size, terrainSettings));
    }
예제 #9
0
        public static void Decorate(Chunk chunk, double[,] terrainHeightMap, OverworldTerrain ot, World world)
        {
            var noise = new TerrainNoise(ot.settings);

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    var        b         = ChunkBiome.GetBiome((chunk.X << 4) + x, (chunk.Z << 4) + z, ot);
                    var        blockPos  = new Vector(x, (int)terrainHeightMap[x, z], z);
                    IDecorator decorator = DecoratorFactory.GetDecorator(b, chunk, blockPos, noise);
                    decorator.Decorate();
                    GenerateTrees(world, blockPos + (chunk.X << 4, 0, chunk.Z << 4), decorator.Features, noise);
                }
            }
        }
예제 #10
0
        public static TerrainNoise makeTerrainNoise(NoiseSource noiseSource)
        {
            GameObject     gameObject     = new GameObject();
            UnityNoiseBase unityNoise     = noiseSource(gameObject);
            TerrainNoise   terrainNoise   = gameObject.AddComponent <TerrainNoise>();
            AnimationCurve animationCurve = new AnimationCurve()
            {
                keys = new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 1) }
            };

            terrainNoise.HeightNoise       = unityNoise;
            terrainNoise.DetailNoise       = unityNoise;
            terrainNoise.HeightAdjustCurve = animationCurve;
            //unityNoise.Awake();
            terrainNoise.Start();
            return(terrainNoise);
        }
예제 #11
0
    private void SpawnGrass(int xChunkPos, int yChunkPos, int localX, VoxelChunk chunk)
    {
        var noiseHeight = terrainNoise.Noise1D(xChunkPos);
        var localY      = Mathf.Floor(Mathf.Abs(noiseHeight - yChunkPos));

        if (TerrainNoise.InRange(yChunkPos, noiseHeight, 1))
        {
            for (int x = -1; x <= 1; x++)
            {
                int maxY = x == 0 ? 13 : 12;
                for (int y = -1; y < maxY; y++)
                {
                    SetPositionVoxel(localX + x, localY + y, chunk, 6);
                }
            }
        }
    }
예제 #12
0
    public void StartUp(VoxelMap map)
    {
        voxelMesh            = FindObjectOfType <VoxelMesh>();
        terrainNoise         = FindObjectOfType <TerrainNoise>();
        terrainMap           = FindObjectOfType <TerrainMap>();
        chunkCollider        = FindObjectOfType <ChunkCollider>();
        chunkObjectSpawner   = FindObjectOfType <ChunkObjectSpawner>();
        chunkSaveLoadManager = FindObjectOfType <ChunkSaveLoadManager>();
        playerRb             = FindObjectOfType <PlayerController>().GetComponent <Rigidbody2D>();

        voxelMap = map;

        terrainNoise.seed = voxelMap.worldScriptableObject.seed;
        terrainNoise.StartUp(voxelMap.voxelResolution, voxelMap.chunkResolution);
        voxelMesh.StartUp(voxelMap.voxelResolution, voxelMap.chunkResolution, voxelMap.viewDistance, useColliders, colliderRadius);

        InvokeRepeating(nameof(UpdateMap), 0.0f, terrainMap.updateInterval);
    }
    public TerrainGenerator(
        int worldWidth,
        int worldHeight,
        float tileScaleWidth,
        float tileScaleHeight,
        int tileUnitWidthSize,
        int tileUnityHeightSize,
        int worldOriginX,
        int worldOriginY)
    {
        this.worldWidth          = worldWidth;
        this.worldHeight         = worldHeight;
        this.tileScaleWidth      = tileScaleWidth;
        this.tileScaleHeight     = tileScaleHeight;
        this.tileUnitWidthSize   = tileUnitWidthSize;
        this.tileUnityHeightSize = tileUnityHeightSize;
        this.worldOriginX        = worldOriginX;
        this.worldOriginY        = worldOriginY;

        this.terrainNoise = new TerrainNoise(new Vector2Int(worldWidth, worldHeight));
    }
예제 #14
0
    private void Awake()
    {
        player               = FindObjectOfType <PlayerController>().transform;
        voxelMap             = FindObjectOfType <VoxelMap>();
        chunkSaveLoadManager = FindObjectOfType <ChunkSaveLoadManager>();
        worldManager         = FindObjectOfType <WorldManager>();
        terrainNoise         = FindObjectOfType <TerrainNoise>();
        worldDataHandler     = FindObjectOfType <WorldDataHandler>();

        isActive = false;

        debugInfo     = transform.GetChild(0);
        worldNameText = debugInfo.GetChild(0).GetComponent <TextMeshProUGUI>();
        worldSeedText = debugInfo.GetChild(1).GetComponent <TextMeshProUGUI>();
        gameModeText  = debugInfo.GetChild(2).GetComponent <TextMeshProUGUI>();
        playerPosText = debugInfo.GetChild(3).GetComponent <TextMeshProUGUI>();
        chunkPosText  = debugInfo.GetChild(4).GetComponent <TextMeshProUGUI>();
        regionPosText = debugInfo.GetChild(5).GetComponent <TextMeshProUGUI>();
        mousePosText  = debugInfo.GetChild(6).GetComponent <TextMeshProUGUI>();

        SetInfoState(isActive);
    }
예제 #15
0
    public void Render()
    {
        generator = new TerrainNoise(layers, lacunarity, persistance);

        var renderer = GetComponent <Renderer>();

        var texture = new Texture2D(width, height);

        texture.filterMode = FilterMode.Point;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                var h = generator.Get((float)(x + offset.x) / width * scale, (float)(y + offset.y) / height * scale);
                texture.SetPixel(x, y, Geo(map.Evaluate(h)));
            }
        }

        texture.Apply();

        renderer.sharedMaterial.mainTexture = texture;
    }
예제 #16
0
        public DynamicPlanet(SystemController controller, GameObject gameObject, int seed, CelestialType type, CelestialBody host = null) : base(controller, gameObject, seed, type, host)
        {
            this.seed       = seed;
            this.gameObject = gameObject;
            position        = gameObject.transform.position;
            regions         = new List <Region>();
            terrain         = new TerrainNoise(this, seed);
            craters         = new List <Crater>();
            Vector3[] vertices  = null;
            int[]     triangles = null;
            Octahedron.GetVerticesAndTriangles(ref vertices, ref triangles);
            for (int i = 0; i < triangles.Length; i += 3)
            {
                int t1 = triangles[i + 0];
                int t2 = triangles[i + 1];
                int t3 = triangles[i + 2];

                Vector3 A = vertices[t1].normalized * radius;
                Vector3 B = vertices[t2].normalized * radius;
                Vector3 C = vertices[t3].normalized * radius;

                regions.Add(new Region(this, null, A, B, C, 0));
            }
        }
예제 #17
0
    private static async Task GenerateFloraAsync(World world, Vector pos, DecoratorFeatures features, TerrainNoise noise)
    {
        foreach (var(flora, index) in features.Flora.Select((value, i) => (value, i)))
        {
            if (flora.Frequency == 0)
            {
                continue;
            }
            var floraInstance = Activator.CreateInstance(flora.FloraType, world) as BaseFlora;
            if (floraInstance is null)
            {
                continue;
            }

            var  noiseVal = noise.Decoration(pos.X, -33 + (index * 22), pos.Z);
            var  freq     = flora.Frequency / 200.0;
            bool isFlora  = noiseVal > 0.9 && noiseVal <= freq + 0.9;
            if (!isFlora)
            {
                continue;
            }

            await floraInstance.GenerateFloraAsync(pos, noise.settings.Seed, flora.Radius, flora.Density);
        }
    }
예제 #18
0
 private void Awake()
 {
     terrainNoise = FindObjectOfType <TerrainNoise>();
     voxelMap     = FindObjectOfType <VoxelMap>();
 }
예제 #19
0
        public IEnumerator NoiseOutputsConnect(NoiseSource noiseSource)
        {
            // NOTE: Unity heightmaps are y,x indexed, even though it is inconsistent with everything else.

            TerrainNoise terrainNoise = makeTerrainNoise(noiseSource);

            float[,] middleMap = new float[3, 3];
            float[,] rightMap  = new float[3, 3];
            float[,] upMap     = new float[3, 3];
            float[,] leftMap   = new float[3, 3];
            float[,] downMap   = new float[3, 3];

            terrainNoise.FillHeightMapNoise(0, 0, middleMap);
            terrainNoise.FillHeightMapNoise(2, 0, rightMap);
            terrainNoise.FillHeightMapNoise(0, 2, upMap);
            terrainNoise.FillHeightMapNoise(-2, 0, leftMap);
            terrainNoise.FillHeightMapNoise(0, -2, downMap);

            foreach (KeyValuePair <string, float[, ]> pair in new Dictionary <string, float[, ]>()
            {
                { "rightMap", rightMap },
                { "upMap", upMap },
                { "leftMap", leftMap },
                { "downMap", downMap }
            })
            {
                for (int x = 0; x < 3; x++)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int x2 = 0; x2 < 3; x2++)
                        {
                            for (int y2 = 0; y2 < 3; y2++)
                            {
                                if (middleMap[y, x] == pair.Value[y, x])
                                {
                                    Debug.Log($"MiddleMap coordinates {y},{x} matches {pair.Key} {y2},{x2}");
                                }
                            }
                        }
                    }
                }
                Debug.Log(pair.Key);
            }

            Assert.AreEqual(middleMap[0, 2], rightMap[0, 0]);
            Assert.AreEqual(middleMap[1, 2], rightMap[1, 0]);
            Assert.AreEqual(middleMap[2, 2], rightMap[2, 0]);

            Assert.AreEqual(middleMap[2, 0], upMap[0, 0]);
            Assert.AreEqual(middleMap[2, 1], upMap[0, 1]);
            Assert.AreEqual(middleMap[2, 2], upMap[0, 2]);

            Assert.AreEqual(middleMap[0, 0], leftMap[0, 2]);
            Assert.AreEqual(middleMap[1, 0], leftMap[1, 2]);
            Assert.AreEqual(middleMap[2, 0], leftMap[2, 2]);

            Assert.AreEqual(middleMap[0, 0], downMap[2, 0]);
            Assert.AreEqual(middleMap[0, 1], downMap[2, 1]);
            Assert.AreEqual(middleMap[0, 2], downMap[2, 2]);

            yield return(null);
        }
예제 #20
0
        private static void GenerateTrees(World world, Vector pos, DecoratorFeatures features, TerrainNoise noise)
        {
            foreach (var(tree, index) in features.Trees.Select((value, i) => (value, i)))
            {
                if (tree.Frequency == 0)
                {
                    continue;
                }
                var treeInstance = Activator.CreateInstance(tree.TreeType, world) as BaseTree;

                // Use a different noisemap for each tree type by setting another Y value.
                var  noiseVal = noise.Decoration(pos.X, -45 + (index * 10), pos.Z);
                var  freq     = tree.Frequency / 100.0;
                bool isTree   = noiseVal > 0.8 && noiseVal <= freq + 0.8;
                if (!isTree)
                {
                    continue;
                }

                int heightVariance = (int)(((noiseVal - 0.8) * 100) - (freq / 2));
                GrowTree(pos, treeInstance, heightVariance);
            }
        }