Exemple #1
0
        }                                                                                               //no extend, non-generic

        public void Add(SpatialHash addHash)
        {
            if (addHash.cells.Length != cells.Length)
            {
                UnityEngine.Debug.LogError("Add SpatialHash: cell number is different"); return;
            }
            for (int c = 0; c < cells.Length; c++)
            {
                cells[c].objs.AddRange(addHash.cells[c].objs);
                Count += cells[c].objs.Count;
            }
        }
Exemple #2
0
        public void ChangeResolution(int newResolution)
        {
            SpatialHash newHash = new SpatialHash(offset, size, newResolution);

            foreach (SpatialObject obj in AllObjs())
            {
                newHash.Add(obj);
            }

            resolution = newResolution;
            cells      = newHash.cells;
        }
Exemple #3
0
        public SpatialHash Copy()
        {
            SpatialHash result = new SpatialHash(offset, size, resolution);

            for (int i = 0; i < cells.Length; i++)
            {
                result.cells[i].min  = cells[i].min;
                result.cells[i].max  = cells[i].max;
                result.cells[i].objs = new List <SpatialObject>(cells[i].objs);

                List <SpatialObject> objs = result.cells[i].objs;
                for (int o = objs.Count - 1; o >= 0; o--)
                {
                    objs[o] = objs[o].Copy();
                }
            }
            result.Count = Count;
            return(result);
        }
Exemple #4
0
            public void RandomScatter(int count, SpatialHash spatialHash, InstanceRandom rnd, Matrix probMatrix)
            {
                int candidatesNum = (int)(uniformity * 100);

                if (candidatesNum < 1)
                {
                    candidatesNum = 1;
                }

                for (int i = 0; i < count; i++)
                {
                    Vector2 bestCandidate = Vector3.zero;
                    float   bestDist      = 0;

                    for (int c = 0; c < candidatesNum; c++)
                    {
                        Vector2 candidate = new Vector2((spatialHash.offset.x + 1) + (rnd.Random() * (spatialHash.size - 2.01f)), (spatialHash.offset.y + 1) + (rnd.Random() * (spatialHash.size - 2.01f)));

                        //checking if candidate available here according to probability map
                        //if (probMatrix!=null && probMatrix[candidate] < rnd.Random()+0.0001f) continue;

                        //checking if candidate is the furthest one
                        float dist = spatialHash.MinDist(candidate);

                        //distance to the edge
                        float bd = (candidate.x - spatialHash.offset.x) * 2; if (bd < dist)
                        {
                            dist = bd;
                        }
                        bd = (candidate.y - spatialHash.offset.y) * 2; if (bd < dist)
                        {
                            dist = bd;
                        }
                        bd = (spatialHash.offset.x + spatialHash.size - candidate.x) * 2; if (bd < dist)
                        {
                            dist = bd;
                        }
                        bd = (spatialHash.offset.y + spatialHash.size - candidate.y) * 2; if (bd < dist)
                        {
                            dist = bd;
                        }

                        if (dist > bestDist)
                        {
                            bestDist = dist; bestCandidate = candidate;
                        }
                    }

                    if (bestDist > 0.001f)
                    {
                        spatialHash.Add(bestCandidate, 0, 0, 1);                         //adding only if some suitable candidate found
                    }
                }

                //masking
                for (int c = 0; c < spatialHash.cells.Length; c++)
                {
                    SpatialHash.Cell cell = spatialHash.cells[c];
                    for (int i = cell.objs.Count - 1; i >= 0; i--)
                    {
                        Vector2 pos = cell.objs[i].pos;

                        if (pos.x < spatialHash.offset.x + safeBorders ||
                            pos.y < spatialHash.offset.y + safeBorders ||
                            pos.x > spatialHash.offset.x + spatialHash.size - safeBorders ||
                            pos.y > spatialHash.offset.y + spatialHash.size - safeBorders)
                        {
                            cell.objs.RemoveAt(i); continue;
                        }

                        if (probMatrix != null && probMatrix[pos] < rnd.Random() + 0.0001f)
                        {
                            cell.objs.RemoveAt(i); continue;
                        }
                    }
                }
            }
Exemple #5
0
            public void Generate(SpatialHash spatialHash, int seed, Matrix probability)
            {
                InstanceRandom rnd = new InstanceRandom(seed ^ this.seed);

                RandomScatter(count, spatialHash, rnd, probability);
            }
Exemple #6
0
        //public MapMagic.GeneratorsAsset mapMagicGens;
                #endif

        public void Generate(Data.Area area, Func <float, bool> stop = null)
        {
            if (area.pinned)
            {
                return;
            }
            change = false;
            if (stop != null && stop(0))
            {
                return;
            }

            //special case for preserving a demo scene on generator change
//			if (area.coord.x==0 && area.coord.z==0) return;
            Data.Area savedArea = null;
            if (leaveDemoUntouched && area.coord.x == 0 && area.coord.z == 0)
            {
                savedArea = (Data.Area)area.Clone();
            }

            if (generatorType == GeneratorType.Planar)
            {
                area.ClearLand();
                area.ClearObjects();
                area.ClearGrass();

                Matrix matrix = new Matrix(area.rect);
                planarGen.Generate(matrix, stop);

                area.AddLayer(matrix, planarGen.blockType, heightFactor: 1, noise: null);
            }

            if (generatorType == GeneratorType.Noise)
            {
                area.ClearLand();
                area.ClearObjects();
                area.ClearGrass();

                Noise noise = new Noise(123, permutationCount: 512);                //random to floor floats

                Matrix noiseMatrix = new Matrix(area.rect);

                if (stop != null && stop(0))
                {
                    return;
                }
                if (noiseGen.enabled)
                {
                    noiseGen.Generate(noiseMatrix, seed, stop);
                }

                if (stop != null && stop(0))
                {
                    return;
                }
                if (curveGen.enabled)
                {
                    curveGen.Generate(noiseMatrix, stop);
                }

                if (stop != null && stop(0))
                {
                    return;
                }
                area.AddLayer(noiseMatrix, noiseGen.blockType, heightFactor: heightFactor, noise: noise);              //TODO: set block types instead of magical numbers

                if (slopeGen.enabled)
                {
                    if (stop != null && stop(0))
                    {
                        return;
                    }
                    Matrix slopeMatrix = slopeGen.Generate(noiseMatrix, stop);
                    area.PaintLayer(slopeMatrix, slopeGen.blockType, noise: noise, paintThickness: slopeGen.thickness);
                }

                if (cavityGen.enabled)
                {
                    if (stop != null && stop(0))
                    {
                        return;
                    }
                    Matrix cavityMatrix = cavityGen.Generate(noiseMatrix, stop);
                    area.PaintLayer(cavityMatrix, cavityGen.blockType, noise: noise, paintThickness: cavityGen.thickness);
                }

                Matrix blurMatrix;
                if (blurGen.enabled)
                {
                    if (stop != null && stop(0))
                    {
                        return;
                    }
                    blurMatrix = blurGen.Generate(noiseMatrix, stop);
                    blurMatrix.Max(noiseMatrix);
                    area.ClampAppendLayer(blurMatrix, blurGen.blockType, noise: noise, heightFactor: heightFactor);
                }
                else
                {
                    blurMatrix = noiseMatrix;
                }

                if (stainsGen.enabled)
                {
                    Matrix matrix = area.GetSoilMatrix(stainsGen.soilOpacity);
                    //Matrix stains = new Matrix(area.rect);

                    stainsGen.Generate(matrix, seed, stop);
                    area.PaintLayer(matrix, stainsGen.blockType, noise: noise, paintThickness: stainsGen.thickness);
                }

                if (noiseGenB.enabled)
                {
                    Matrix matrix = new Matrix(area.rect);
                    noiseGenB.Generate(matrix, seed, stop);
                    area.SetLayer(matrix, null, noiseGenB.blockType, heightFactor: heightFactor, noise: noise);
                }

                if (scatterGen.enabled)
                {
                    if (stop != null && stop(0))
                    {
                        return;
                    }

                    SpatialHash spatialHash = new SpatialHash(new Vector2(area.rect.offset.x, area.rect.offset.z), area.rect.size.x, 16);

                    Matrix soil = area.GetSoilMatrix(scatterGen.soilOpacity);

                    scatterGen.Generate(spatialHash, seed, soil);

                    foreach (SpatialObject obj in spatialHash.AllObjs())
                    {
                        int x = (int)(obj.pos.x + 0.5f);
                        int z = (int)(obj.pos.y + 0.5f);
                        int y = (int)((obj.height + blurMatrix[x, z]) * heightFactor);
                        area.AddObject(new CoordDir(x, y, z), (short)scatterGen.blockType);
                    }
                }

                for (int g = 0; g < grassGens.gens.Length; g++)
                {
                    GrassGenerator grassGen = grassGens.gens[g];
                    //if (grassGen.enabled)
                    {
                        if (stop != null && stop(0))
                        {
                            return;
                        }

                        Matrix grassMatrix = area.GetSoilMatrix(grassGen.soilOpacity);

                        grassGen.Generate(grassMatrix, seed);

                        area.SetGrassLayer(grassMatrix, (byte)grassGen.grassType, 1, noise);
                    }
                }
            }

            else if (generatorType == GeneratorType.Heightmap)
            {
                area.ClearLand();
                area.ClearObjects();
                area.ClearGrass();

                Noise noise = new Noise(123, permutationCount: 512);                //random to floor floats

                Matrix matrix = new Matrix(area.rect);

                if (stop != null && stop(0))
                {
                    return;
                }
                if (standaloneHeightGen.enabled)
                {
                    standaloneHeightGen.Generate(matrix, seed, stop);
                }
                area.AddLayer(matrix, noiseGen.blockType, heightFactor: heightFactor, noise: noise);               //TODO: set block types instead of magical numbers
            }

            else if (generatorType == GeneratorType.MapMagic)
            {
                                #if MAPMAGIC
                if (stop != null && stop(0))
                {
                    return;
                }
                if (area.results == null)
                {
                    area.results = new MapMagic.Chunk.Results();
                }
                //MapMagic.Chunk.Size size = new MapMagic.Chunk.Size(area.rect.size.x,area.rect.size.x,heightFactor);

                if (stop != null && stop(0))
                {
                    return;
                }
                if (mapMagicGens != null)
                {
                    //mapMagicGens.Calculate(area.rect.offset.x, area.rect.offset.z, area.rect.size.x, area.results,  new MapMagic.Chunk.Size(area.rect.size.x,area.rect.size.x,heightFactor), seed, stop);
                    mapMagicGens.Generate(area.results, area.rect.offset.x, area.rect.offset.z, area.rect.size.x, area.rect.size.x, heightFactor, seed, stop);
                }
                else
                {
                    area.ClearLand(); area.ClearObjects(); area.ClearGrass();
                }
                                #else
                area.ClearLand(); area.ClearObjects(); area.ClearGrass();
                                #endif
            }

            if (stop != null && stop(0))
            {
                return;
            }
            if (removeThinLayers)
            {
                area.RemoveThinLayers(minLayerThickness);
            }

            if (stop != null && stop(0))
            {
                return;
            }
            if (polish)
            {
                area.Polish();
            }

            //special case for preserving a demo scene on generator change
            if (leaveDemoUntouched && area.coord.x == 0 && area.coord.z == 0)
            {
                Matrix mask = new Matrix(new CoordRect(0, 0, area.lines.Length, area.lines.Length));
                for (int x = 0; x < mask.rect.size.x; x++)
                {
                    for (int z = 0; z < mask.rect.size.z; z++)
                    {
                        int distFromEdge = Mathf.Min(x, mask.rect.size.x - x, z, mask.rect.size.z - z);
                        mask[x, z] = Mathf.Clamp01(distFromEdge / 50f);
                    }
                }

                Matrix maskInverted = (Matrix)mask.Clone(); maskInverted.InvertOne();

                area.MixAreas(new Data.Area[] { (Data.Area)area.Clone(), savedArea }, new Matrix[] { maskInverted, mask });
                area.objects = savedArea.objects;
            }

            //area.generated = true;
            //area.serializable = true;
        }