/// <summary> /// Launchs foliage population asynchronous task /// </summary> /// <param name="scene">Scene</param> /// <param name="node">Foliage Node</param> /// <param name="map">Foliage map</param> /// <param name="description">Terrain vegetation description</param> /// <param name="gbbox">Relative bounding box to plant</param> /// <param name="delay">Task delay</param> public void Plant(Scene scene, QuadTreeNode node, FoliageMap map, FoliageMapChannel description, BoundingBox gbbox, int delay) { if (!this.Planting) { //Start planting task this.CurrentNode = node; this.Channel = description.Index; this.Planting = true; Task .Run(async() => { await Task.Delay(delay); return(PlantTask(scene, node, map, description, gbbox)); }) .ContinueWith((t) => { this.Planting = false; this.Planted = true; this.foliageData = t.Result; }); } }
/// <summary> /// Asynchronous planting task /// </summary> /// <param name="scene">Scene</param> /// <param name="node">Node to process</param> /// <param name="map">Foliage map</param> /// <param name="description">Vegetation task</param> /// <param name="gbbox">Relative bounding box to plant</param> /// <returns>Returns generated vertex data</returns> private static IEnumerable <VertexBillboard> PlantTask(Scene scene, QuadTreeNode node, FoliageMap map, FoliageMapChannel description, BoundingBox gbbox) { if (node == null) { return(new VertexBillboard[] { }); } List <VertexBillboard> vertexData = new List <VertexBillboard>(MAX); Vector2 min = new Vector2(gbbox.Minimum.X, gbbox.Minimum.Z); Vector2 max = new Vector2(gbbox.Maximum.X, gbbox.Maximum.Z); Random rnd = new Random(description.Seed); var bbox = node.BoundingBox; int count = (int)Math.Min(MAX, MAX * description.Saturation); int iterations = MAX * 2; //Number of points while (count > 0 && iterations > 0) { iterations--; Vector3 pos = new Vector3( rnd.NextFloat(bbox.Minimum.X, bbox.Maximum.X), bbox.Maximum.Y + 1f, rnd.NextFloat(bbox.Minimum.Z, bbox.Maximum.Z)); bool plant = false; if (map != null) { var c = map.GetRelative(pos, min, max); if (c[description.Index] > 0) { plant = rnd.NextFloat(0, 1) < (c[description.Index]); } } else { plant = true; } if (plant) { var size = new Vector2( rnd.NextFloat(description.MinSize.X, description.MaxSize.X), rnd.NextFloat(description.MinSize.Y, description.MaxSize.Y)); var planted = Plant(scene, pos, size, out var res); if (planted) { vertexData.Add(res); count--; } } else { count--; } } return(vertexData.ToArray()); }