示例#1
0
        /// <summary>
        /// Resource disposal
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                for (int i = 0; i < this.foliageBuffers.Count; i++)
                {
                    this.foliageBuffers[i]?.Dispose();
                    this.foliageBuffers[i] = null;
                }
                this.foliageBuffers.Clear();

                foreach (var item in this.foliagePatches.Values)
                {
                    foreach (var value in item)
                    {
                        value?.Dispose();
                    }
                }
                this.foliagePatches.Clear();

                this.foliageMap?.Dispose();
                this.foliageMap = null;

                for (int i = 0; i < this.foliageMapChannels.Count; i++)
                {
                    this.foliageMapChannels[i]?.Dispose();
                    this.foliageMapChannels[i] = null;
                }
                this.foliageMapChannels.Clear();

                this.textureRandom?.Dispose();
                this.textureRandom = null;
            }
        }
示例#2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="game">Game</param>
        /// <param name="bufferManager">Buffer manager</param>
        /// <param name="description">Description</param>
        public GroundGardener(Scene scene, GroundGardenerDescription description) :
            base(scene, description)
        {
            if (description == null)
            {
                throw new EngineException("A gardener description should be specified.");
            }

            this.textureRandom = this.Game.ResourceManager.CreateResource(Guid.NewGuid(), 1024, -1, 1, 24);

            this.foliageSphere = new BoundingSphere(Vector3.Zero, description.VisibleRadius);

            //Material
            this.material = new MeshMaterial()
            {
                Material = description.Material != null?description.Material.GetMaterial() : Material.Default
            };

            //Read foliage textures
            string contentPath = description.ContentPath;

            if (!string.IsNullOrEmpty(description.VegetationMap))
            {
                var foliageMapImage = new ImageContent()
                {
                    Streams = ContentManager.FindContent(contentPath, description.VegetationMap),
                };
                this.foliageMap = FoliageMap.FromStream(foliageMapImage.Stream);
            }

            for (int i = 0; i < description.Channels.Length; i++)
            {
                var channelDesc = description.Channels[i];
                if (channelDesc?.Enabled == true)
                {
                    var newChannel = CreateChannel(channelDesc, i, contentPath);

                    this.foliageMapChannels.Add(newChannel);
                }
            }

            for (int i = 0; i < MaxFoliageBuffers; i++)
            {
                this.foliageBuffers.Add(new FoliageBuffer(this.Game, this.BufferManager, description.Name));
            }
        }
示例#3
0
            /// <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;
                    });
                }
            }
示例#4
0
            /// <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());
            }