Exemple #1
0
    private BiomeCenter GenerateBiomeCenter(SectionCoord coord)
    {
        BiomeCenter center = new BiomeCenter();

        center.coord = coord;
        NotRandom.RNG rng = new NotRandom.RNG(NotRandom.Hash2Int(seedHash,
                                                                 center.coord.GetHashCode()));

        float nx = center.coord.x * biomeCenterSpacing + ((rng.Value() *
                                                           maxBiomeCenterOffset * 2) - maxBiomeCenterOffset);
        float nz = center.coord.z * biomeCenterSpacing + ((rng.Value() *
                                                           maxBiomeCenterOffset * 2) - maxBiomeCenterOffset);

        center.center = new Vector3(nx, 1f, nz);

        int index = (int)(rng.ValueUInt() % totalBiomeFrequency);

        for (int i = 0; i < biomes.Count; i++)
        {
            if (index >= 0 && index < biomes[i].relativeFrequency)
            {
                center.biome = biomes[i];
                break;
            }
            index -= biomes[i].relativeFrequency;
        }
        return(center);
    }
Exemple #2
0
    private void CalculateBiomeBounds(SectionCoord coord)
    {
        BiomeCenter target = SafeGetBiomeCenter(coord);

        if (target.boundsCalculated)
        {
            return;
        }

        List <BiomeCenter>  neighbors = new List <BiomeCenter>();
        List <SectionCoord> coords;
        Dictionary <SectionCoord, Plane> properBounds =
            new Dictionary <SectionCoord, Plane>();
        List <Plane> weakBounds = new List <Plane>();
        Plane        plane;
        Vector3      self = target.center;
        Vector3      other, middle;

        coords = SectionsInRadius(coord, 2.75f);

        for (int i = 1; i < coords.Count; i++)
        {
            neighbors.Add(SafeGetBiomeCenter(coords[i]));
        }

        for (int i = 0; i < neighbors.Count; i++)
        {
            other  = neighbors[i].center;
            middle = (self + other) / 2f;
            if (neighbors[i].boundsCalculated)
            {
                plane = neighbors[i].properBounds[coord].flipped;
                properBounds.Add(neighbors[i].coord, plane);
            }
            else
            {
                plane = new Plane((self - other).normalized, middle);
                properBounds.Add(neighbors[i].coord, plane);
            }
            weakBounds.Add(new Plane(plane.normal,
                                     middle - plane.normal * (biomeBlend / 2f)));
        }
        SimplifyConvexPlanes(weakBounds, self);
        lock (target)
        {
            if (!target.boundsCalculated)
            {
                target.properBounds     = properBounds;
                target.weakBounds       = weakBounds;
                target.boundsCalculated = true;
            }
        }
    }
Exemple #3
0
    public List <BiomeStrength> GetBiomes(Vector3 vLoc)
    {
        List <BiomeStrength> output = new List <BiomeStrength>(biomes.Count);

        Vector3      loc      = new Vector3(vLoc.x, 0f, vLoc.z);
        Vector3      biomeLoc = loc / biomeCenterSpacing;
        SectionCoord coord    = new SectionCoord(Mathf.RoundToInt(biomeLoc.x),
                                                 Mathf.RoundToInt(biomeLoc.z));

        BiomeCenter center = SafeGetBiomeCenter(coord);
        float       weakDist, dist, totalStrength;

        if (!center.boundsCalculated)
        {
            CalculateBiomeBounds(coord);
        }

        weakDist = Mathf.Infinity;

        for (int k = 0; weakDist > biomeBlend &&
             k < center.weakBounds.Count; k++)
        {
            dist = center.weakBounds[k].GetDistanceToPoint(loc);
            if (dist < weakDist)
            {
                weakDist = dist;
            }
        }
        if (weakDist > biomeBlend)
        {
            output.Add(new BiomeStrength(center.biome, 1f));
            return(output);
        }

        List <SectionCoord> coords = SectionsInRadius(coord, 2.75f);

        for (int i = 0; i < coords.Count; i++)
        {
            center = SafeGetBiomeCenter(coords[i]);
            if (!center.boundsCalculated)
            {
                CalculateBiomeBounds(coords[i]);
            }

            weakDist = Mathf.Infinity;

            for (int k = 0; weakDist >= 0.0f &&
                 k < center.weakBounds.Count; k++)
            {
                dist = center.weakBounds[k].GetDistanceToPoint(loc);
                if (dist < weakDist)
                {
                    weakDist = dist;
                }
            }
            if (weakDist > biomeBlend)
            {
                output.Clear();
                output.Add(new BiomeStrength(center.biome, 1f));
                return(output);
            }
            if (weakDist >= 0.0f)
            {
                int j = 0;
                for (; j < output.Count; j++)
                {
                    if (output[j].biome == center.biome)
                    {
                        output[j].strength += (weakDist / biomeBlend);
                        break;
                    }
                }
                if (j == output.Count)
                {
                    output.Add(new BiomeStrength(center.biome, weakDist / biomeBlend));
                }
            }
        }

        totalStrength = 0f;
        for (int i = 0; i < output.Count; i++)
        {
            output[i].strength =
                Mathf.Pow(Mathf.Clamp01(output[i].strength), 2f);
            totalStrength += output[i].strength;
        }
        for (int i = 0; i < output.Count; i++)
        {
            output[i].strength /= totalStrength;
        }
        return(output);
    }
Exemple #4
0
    private IEnumerator GenerateSection_CR(SectionCoord coord)
    {
        TerrainSection sec;

        if (terrains.TryGetValue(coord, out sec) && sec != null &&
            sec.terrain != null)
        {
            if (numGenThreads > 0)
            {
                numGenThreads--;
            }
            yield break;
        }
        if (sec == null)
        {
            sec = new TerrainSection(coord);
        }

        float[,] heightmap  = null;
        float[,,] alphamaps = null;
        int                 bx, bz;
        float               height;
        Vector3             targLoc;
        GameObject          go;
        BiomeData           bd;
        List <SectionCoord> biomeCenters;

        List <Biome> containedBiomes = null;
        List <DetailPrototypeData> detailPrototypeDatas = null;
        List <int[, ]>             detailMaps           = null;
        List <TreePrototypeData>   treePrototypeDatas   = null;
        List <TreeInstance>        treeInstances        = null;

        Thread heightThread = new Thread(() =>
        {
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.BeginThreadProfiling(
                "Heightmap", "" + coord.x + ":" + coord.z);
#endif
            heightmap = GenerateHeightmap(coord);
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.EndThreadProfiling();
#endif
        });
        Thread alphaThread = new Thread(() =>
        {
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.BeginThreadProfiling(
                "Alphamap", "" + coord.x + ":" + coord.z);
#endif
            alphamaps = GenerateAlphamaps(coord, out containedBiomes);
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.EndThreadProfiling();
#endif
        });
        Thread detailThread = new Thread(() =>
        {
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.BeginThreadProfiling(
                "Detailmap", "" + coord.x + ":" + coord.z);
#endif
            detailMaps = GenerateDetailMaps(coord,
                                            out detailPrototypeDatas);
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.EndThreadProfiling();
#endif
        });
        Thread treeThread = new Thread(() =>
        {
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.BeginThreadProfiling(
                "Treemap", "" + coord.x + ":" + coord.z);
#endif
            treeInstances = GenerateTreeInstances(coord,
                                                  out treePrototypeDatas);
#if DEBUG_THREADS
            UnityEngine.Profiling.Profiler.EndThreadProfiling();
#endif
        });

        yield return(null);

        treeThread.Start();
        yield return(null);

        heightThread.Start();
        yield return(null);

        alphaThread.Start();
        yield return(null);

        detailThread.Start();
        yield return(new WaitUntil(() => (heightmap != null &&
                                          alphamaps != null && detailMaps != null &&
                                          treeInstances != null && !loadingSection)));

        TerrainLayer[] terrainLayers = new TerrainLayer[containedBiomes.Count];
        loadingSection = true;
        sectionLoading = coord;

        TerrainData data = new TerrainData();

        data.heightmapResolution = genSettings.heightMapRes;
        yield return(null);

        data.alphamapResolution = genSettings.alphaMapRes;
        data.SetDetailResolution(genSettings.detailMapRes,
                                 genSettings.detailMapResPerPatch);
        data.size = new Vector3(genSettings.length, genSettings.height,
                                genSettings.length);
        yield return(null);

        data.SetHeights(0, 0, heightmap);
        yield return(null);

        for (int i = 0; i < containedBiomes.Count; i++)
        {
            terrainLayers[i] = containedBiomes[i].terrainLayer;
        }

        DetailPrototype[] detailPrototypes = null;
        if (detailPrototypeDatas.Count > 0)
        {
            detailPrototypes = new DetailPrototype[detailPrototypeDatas.Count];
        }
        for (int i = 0; i < detailPrototypeDatas.Count; i++)
        {
            DetailPrototype     dp  = detailPrototypes[i] = new DetailPrototype();
            DetailPrototypeData dpd = detailPrototypeDatas[i];
            dp.bendFactor   = dpd.bendFactor;
            dp.dryColor     = dpd.dryColor;
            dp.healthyColor = dpd.healthyColor;
            dp.maxHeight    = dpd.maxHeight;
            dp.maxWidth     = dpd.maxWidth;
            dp.minHeight    = dpd.minHeight;
            dp.minWidth     = dpd.minWidth;
            dp.noiseSpread  = dpd.noiseSpread;
            if (dpd.prototype != null)
            {
                dp.prototype        = dpd.prototype;
                dp.usePrototypeMesh = true;
            }
            else
            {
                dp.prototypeTexture = dpd.prototypeTexture;
                dp.usePrototypeMesh = false;
            }
            dp.renderMode = dpd.renderMode;
        }
        yield return(null);

        data.terrainLayers = terrainLayers;
        data.SetAlphamaps(0, 0, alphamaps);
        yield return(null);

        TreePrototype[] treePrototypes = null;
        if (treePrototypeDatas.Count > 0)
        {
            treePrototypes = new TreePrototype[treePrototypeDatas.Count];
        }
        for (int i = 0; i < treePrototypeDatas.Count; i++)
        {
            TreePrototype tp = treePrototypes[i] = new TreePrototype();
            tp.bendFactor = treePrototypeDatas[i].bendFactor;
            tp.prefab     = treePrototypeDatas[i].prefab;
        }
        yield return(null);

        if (detailPrototypes != null)
        {
            data.detailPrototypes = detailPrototypes;
            yield return(null);

            for (int i = 0; i < detailMaps.Count; i++)
            {
                data.SetDetailLayer(0, 0, i, detailMaps[i]);
            }
            yield return(null);
        }
        if (treePrototypes != null)
        {
            data.treePrototypes = treePrototypes;
            yield return(null);

            data.SetTreeInstances(treeInstances.ToArray(), true);
        }
        yield return(null);

        data.RefreshPrototypes();

        yield return(null);

        GameObject obj = Terrain.CreateTerrainGameObject(data);

        sec.terrain = obj.GetComponent <Terrain>();

        sec.terrain.treeBillboardDistance = 150;
        sec.terrain.materialTemplate      = terrainMaterial;

        sec.terrain.allowAutoConnect = true;
        obj.transform.position       = new Vector3(coord.x * genSettings.length -
                                                   genSettings.length / 2, 0f, coord.z * genSettings.length -
                                                   genSettings.length / 2);
        yield return(null);

        sec.terrain.Flush();
        yield return(null);

        bx = Mathf.RoundToInt((coord.x * genSettings.length) /
                              biomeCenterSpacing);
        bz = Mathf.RoundToInt((coord.z * genSettings.length) /
                              biomeCenterSpacing);
        biomeCenters = SectionsInRadius(new SectionCoord(bx, bx), 2);
        for (int i = 0; i < biomeCenters.Count; i++)
        {
            BiomeCenter center = SafeGetBiomeCenter(biomeCenters[i]);
            height  = sec.terrain.SampleHeight(center.center);
            targLoc = new Vector3(center.center.x, height, center.center.z +
                                  sec.terrain.GetPosition().y);
            if (sec.terrain.terrainData.bounds.Contains(targLoc -
                                                        sec.terrain.transform.position))
            {
                if (center.biome.ambientPrefab != null)
                {
                    go = Instantiate(center.biome.ambientPrefab, targLoc,
                                     Quaternion.identity, sec.terrain.transform);
                }
                else
                {
                    go = new GameObject();
                    go.transform.position = targLoc;
                    go.transform.parent   = sec.terrain.transform;
                }
                bd            = go.AddComponent <TerrainManager.BiomeData>();
                bd.biome      = center.biome;
                bd.center     = targLoc;
                bd.boundaries = center.properBounds.Values.ToList();
                SimplifyConvexPlanes(bd.boundaries, bd.center);
            }
        }

        yield return(null);

        terrains.Add(coord, sec);
        if (numGenThreads > 0)
        {
            numGenThreads--;
        }
        generating.Remove(coord);
        if (coord.Equals(sectionLoading))
        {
            loadingSection = false;
        }
    }