45 lines
1.6 KiB
C#
45 lines
1.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Assets.Common;
|
|
using Assets.PointDistribution;
|
|
|
|
namespace Assets.AnnotationPass
|
|
{
|
|
public class ForestPass : IAnnotationPass
|
|
{
|
|
public const string TreesProperty = "Trees";
|
|
|
|
public double TreeRadius { get; set; } = 2;
|
|
public double ForestRatio { get; set; } = .4;
|
|
public double Scale { get; set; } = .01;
|
|
public double Lacunarity { get; set; } = 1.7;
|
|
public double Dampening { get; set; } = .7;
|
|
|
|
public void Annotate(Map map)
|
|
{
|
|
var random = new Random(map.Seed + 2137);
|
|
var sampler = new PoissonDiskSampler(TreeRadius) { Generator = random };
|
|
var perlin = new PerlinNoiseGenerator
|
|
{
|
|
Iterations = 4,
|
|
Scale = (float)Scale,
|
|
Lacunarity = (float)Lacunarity,
|
|
Decay = (float)Dampening,
|
|
Offset = new Point(random.NextDouble() * 150, random.NextDouble() * 150)
|
|
};
|
|
|
|
var points = sampler
|
|
.Generate(map.Size.Width, map.Size.Height)
|
|
.Where(p => perlin.GetValue(p) < ForestRatio)
|
|
.Select(p => new Tree {
|
|
Placement = p,
|
|
Site = map.Sites.Vertices.FirstOrDefault(site => PointUtils.IsPointInside(p, site.Boundary.Select(n => map.Boundaries[n])))
|
|
})
|
|
.Where(t => t.Site != null)
|
|
.Where(t => t.Site.Tags.Contains(CommonTags.Land) && t.Site.Tags.Contains(CommonTags.Empty))
|
|
;
|
|
|
|
map.SetProperty(TreesProperty, points.ToList());
|
|
}
|
|
}
|
|
} |