Beispiel #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="game">Game</param>
        /// <param name="name">Name</param>
        /// <param name="description">Particle system description</param>
        /// <param name="emitter">Particle emitter</param>
        public ParticleSystemCpu(Game game, string name, ParticleSystemDescription description, ParticleEmitter emitter)
        {
            this.Game = game;
            this.Name = name;

            this.parameters = new ParticleSystemParams(description) * emitter.Scale;

            var imgContent = new ImageContent()
            {
                Streams = ContentManager.FindContent(description.ContentPath, description.TextureName),
            };

            this.Texture      = game.ResourceManager.CreateResource(imgContent);
            this.TextureCount = (uint)imgContent.Count;

            this.Emitter = emitter;
            this.Emitter.UpdateBounds(this.parameters);
            this.MaxConcurrentParticles = this.Emitter.GetMaximumConcurrentParticles(description.MaxDuration);

            this.particles = new VertexCpuParticle[this.MaxConcurrentParticles];

            this.buffer = new EngineBuffer <VertexCpuParticle>(game.Graphics, description.Name, this.particles, true);
            buffer.AddInputLayout(game.Graphics.CreateInputLayout(DrawerPool.EffectDefaultCPUParticles.RotationDraw.GetSignature(), VertexCpuParticle.Input(BufferSlot)));
            buffer.AddInputLayout(game.Graphics.CreateInputLayout(DrawerPool.EffectDefaultCPUParticles.NonRotationDraw.GetSignature(), VertexCpuParticle.Input(BufferSlot)));

            this.TimeToEnd = this.Emitter.Duration + this.parameters.MaxDuration;
        }
        /// <summary>
        /// Contructor
        /// </summary>
        /// <param name="game">Game</param>
        /// <param name="name">Name</param>
        /// <param name="description">Particle system description</param>
        /// <param name="emitter">Emitter</param>
        public ParticleSystemGpu(Game game, string name, ParticleSystemDescription description, ParticleEmitter emitter)
        {
            this.Game = game;
            this.Name = name;

            this.parameters = new ParticleSystemParams(description) * emitter.Scale;

            var imgContent = new ImageContent()
            {
                Streams = ContentManager.FindContent(description.ContentPath, description.TextureName),
            };

            this.Texture      = game.ResourceManager.CreateResource(imgContent);
            this.TextureCount = (uint)imgContent.Count;

            this.Emitter = emitter;
            this.Emitter.UpdateBounds(this.parameters);
            this.MaxConcurrentParticles = this.Emitter.GetMaximumConcurrentParticles(description.MaxDuration);

            this.TimeToEnd = this.Emitter.Duration + this.parameters.MaxDuration;

            var data = Helper.CreateArray(1, new VertexGpuParticle()
            {
                Position     = this.Emitter.Position,
                Velocity     = this.Emitter.Velocity,
                RandomValues = new Vector4(),
                MaxAge       = 0,

                Type         = 0,
                EmissionTime = this.Emitter.Duration,
            });

            int size = this.GetBufferSize();

            this.emittersBuffer  = game.Graphics.CreateBuffer <VertexGpuParticle>(description.Name, data, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None);
            this.drawingBuffer   = game.Graphics.CreateBuffer <VertexGpuParticle>(description.Name, size, ResourceUsage.Default, BindFlags.VertexBuffer | BindFlags.StreamOutput, CpuAccessFlags.None);
            this.streamOutBuffer = game.Graphics.CreateBuffer <VertexGpuParticle>(description.Name, size, ResourceUsage.Default, BindFlags.VertexBuffer | BindFlags.StreamOutput, CpuAccessFlags.None);
            this.inputStride     = default(VertexGpuParticle).GetStride();

            this.emitterBinding   = new[] { new VertexBufferBinding(this.emittersBuffer, this.inputStride, 0) };
            this.drawingBinding   = new[] { new VertexBufferBinding(this.drawingBuffer, this.inputStride, 0) };
            this.streamOutBinding = new[] { new StreamOutputBufferBinding(this.streamOutBuffer, 0) };

            var effect = DrawerPool.EffectDefaultGPUParticles;

            this.streamOutInputLayout   = game.Graphics.CreateInputLayout(effect.ParticleStreamOut.GetSignature(), VertexGpuParticle.Input(BufferSlot));
            this.rotatingInputLayout    = game.Graphics.CreateInputLayout(effect.RotationDraw.GetSignature(), VertexGpuParticle.Input(BufferSlot));
            this.nonRotatingInputLayout = game.Graphics.CreateInputLayout(effect.NonRotationDraw.GetSignature(), VertexGpuParticle.Input(BufferSlot));
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="description">Particle system description</param>
        public ParticleSystemParams(ParticleSystemDescription description) : this()
        {
            this.minHorizontalVelocity = 0f;
            this.maxHorizontalVelocity = 0f;
            this.minVerticalVelocity   = 0f;
            this.maxVerticalVelocity   = 0f;
            this.minRotateSpeed        = 0f;
            this.maxRotateSpeed        = 0f;
            this.minStartSize          = 0f;
            this.maxStartSize          = 0f;
            this.minEndSize            = 0f;
            this.maxEndSize            = 0f;

            this.HorizontalVelocity = Vector2.Zero;
            this.VerticalVelocity   = Vector2.Zero;
            this.RotateSpeed        = Vector2.Zero;
            this.StartSize          = Vector2.Zero;
            this.EndSize            = Vector2.Zero;

            this.MaxDuration           = description.MaxDuration;
            this.MaxDurationRandomness = description.MaxDurationRandomness;

            this.Gravity     = description.Gravity;
            this.EndVelocity = description.EndVelocity;

            this.MinColor = description.MinColor;
            this.MaxColor = description.MaxColor;

            this.Transparent = description.Transparent;
            this.Additive    = description.Additive;

            this.EmitterVelocitySensitivity = description.EmitterVelocitySensitivity;

            this.MinHorizontalVelocity = description.MinHorizontalVelocity;
            this.MaxHorizontalVelocity = description.MaxHorizontalVelocity;
            this.MinVerticalVelocity   = description.MinVerticalVelocity;
            this.MaxVerticalVelocity   = description.MaxVerticalVelocity;
            this.MinRotateSpeed        = description.MinRotateSpeed;
            this.MaxRotateSpeed        = description.MaxRotateSpeed;
            this.MinStartSize          = description.MinStartSize;
            this.MaxStartSize          = description.MaxStartSize;
            this.MinEndSize            = description.MinEndSize;
            this.MaxEndSize            = description.MaxEndSize;
        }
        /// <summary>
        /// Initializes smoke plume particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeSmokePlume(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "SmokePlume",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration = 10,

                MinHorizontalVelocity = -1.0f,
                MaxHorizontalVelocity = +1.0f,

                MinVerticalVelocity = -1.0f,
                MaxVerticalVelocity = +1.0f,

                Gravity = Vector3.Zero,

                EndVelocity = 0.75f,

                MinRotateSpeed = 0.5f,
                MaxRotateSpeed = 1.0f,

                MinStartSize = 1f,
                MaxStartSize = 2f,

                MinEndSize = 5f,
                MaxEndSize = 20f,

                MaxDurationRandomness = 1f,

                EmitterVelocitySensitivity = 1f,

                Transparent = true,
                Additive    = false
            };

            settings.Scale(scale);

            return(settings);
        }
        /// <summary>
        /// Initializes dust particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeDust(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "Dust",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration = 1,

                MinHorizontalVelocity = 0,
                MaxHorizontalVelocity = 0.5f,

                MinVerticalVelocity = -1,
                MaxVerticalVelocity = 1,

                Gravity = new Vector3(0.0f, -0.35f, 0.0f),

                EndVelocity = 0.1f,

                MinColor = Color.SandyBrown * 0.5f,
                MaxColor = Color.SandyBrown,

                MinRotateSpeed = -1,
                MaxRotateSpeed = 1,

                MinStartSize = 0.25f,
                MaxStartSize = 0.5f,

                MinEndSize = 0.5f,
                MaxEndSize = 1f,

                Transparent = true,
                Additive    = false
            };

            settings.Scale(scale);

            return(settings);
        }
        /// <summary>
        /// Initializes explosion with smoke particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeSmokeExplosion(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "SmokeExplosion",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration = 4,

                MinHorizontalVelocity = 0,
                MaxHorizontalVelocity = 5,

                MinVerticalVelocity = -1,
                MaxVerticalVelocity = 5,

                Gravity = new Vector3(0, -20, 0),

                EndVelocity = 0,

                MinColor = Color.LightGray,
                MaxColor = Color.White,

                MinRotateSpeed = -2,
                MaxRotateSpeed = 2,

                MinStartSize = 1,
                MaxStartSize = 1,

                MinEndSize = 10,
                MaxEndSize = 20,

                Transparent = true,
                Additive    = false
            };

            settings.Scale(scale);

            return(settings);
        }
 /// <summary>
 /// Updates the current particle parameters with the specified particle description
 /// </summary>
 /// <param name="other">The other particle description</param>
 public void Update(ParticleSystemDescription other)
 {
     this.MaxDuration           = other.MaxDuration;
     this.MaxDurationRandomness = other.MaxDurationRandomness;
     this.MaxHorizontalVelocity = other.MaxHorizontalVelocity;
     this.MinHorizontalVelocity = other.MinHorizontalVelocity;
     this.MaxVerticalVelocity   = other.MaxVerticalVelocity;
     this.MinVerticalVelocity   = other.MinVerticalVelocity;
     this.Gravity                    = other.Gravity;
     this.EndVelocity                = other.EndVelocity;
     this.MinColor                   = other.MinColor;
     this.MaxColor                   = other.MaxColor;
     this.MinRotateSpeed             = other.MinRotateSpeed;
     this.MaxRotateSpeed             = other.MaxRotateSpeed;
     this.MinStartSize               = other.MinStartSize;
     this.MaxStartSize               = other.MaxStartSize;
     this.MinEndSize                 = other.MinEndSize;
     this.MaxEndSize                 = other.MaxEndSize;
     this.Transparent                = other.Transparent;
     this.EmitterVelocitySensitivity = other.EmitterVelocitySensitivity;
 }
        /// <summary>
        /// Initializes explosion particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeExplosion(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "Explosion",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration           = 1.5f,
                MaxDurationRandomness = 1,

                MinHorizontalVelocity = 1.0f,
                MaxHorizontalVelocity = 1.5f,

                MinVerticalVelocity = -1f,
                MaxVerticalVelocity = 1f,

                EndVelocity = 0,

                MinColor = Color.DarkGray,
                MaxColor = Color.Gray,

                MinRotateSpeed = -1,
                MaxRotateSpeed = 1,

                MinStartSize = 0.25f,
                MaxStartSize = 0.25f,

                MinEndSize = 5,
                MaxEndSize = 10,

                Transparent = true,
                Additive    = true
            };

            settings.Scale(scale);

            return(settings);
        }
        /// <summary>
        /// Initializes porjectile trail particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeProjectileTrail(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "ProjectileTrail",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration           = 0.5f,
                MaxDurationRandomness = 1.5f,

                EmitterVelocitySensitivity = 0.1f,

                MinHorizontalVelocity = -0.1f,
                MaxHorizontalVelocity = 0.1f,

                MinVerticalVelocity = -0.1f,
                MaxVerticalVelocity = 0.1f,

                MinColor = Color.Gray,
                MaxColor = Color.White,

                MinRotateSpeed = 1,
                MaxRotateSpeed = 1,

                MinStartSize = 0.25f,
                MaxStartSize = 0.5f,

                MinEndSize = 0.5f,
                MaxEndSize = 1.0f,

                Transparent = true,
                Additive    = false
            };

            settings.Scale(scale);

            return(settings);
        }
        /// <summary>
        /// Initializes fire particle systems
        /// </summary>
        /// <param name="contentPath">Content path</param>
        /// <param name="texture">Texture</param>
        /// <param name="scale">System scale</param>
        /// <returns>Returns the new generated particle system description</returns>
        public static ParticleSystemDescription InitializeFire(string contentPath, string texture, float scale = 1f)
        {
            ParticleSystemDescription settings = new ParticleSystemDescription
            {
                Name = "Fire",

                ContentPath = contentPath,
                TextureName = texture,

                MaxDuration           = 2,
                MaxDurationRandomness = 1,

                MinHorizontalVelocity = -1f,
                MaxHorizontalVelocity = +1f,

                MinVerticalVelocity = -1f,
                MaxVerticalVelocity = 1f,

                Gravity = new Vector3(0, 0, 0),

                MinColor = new Color(1f, 1f, 1f, 0.85f),
                MaxColor = new Color(1f, 1f, 1f, 1f),

                MinStartSize = 0.1f,
                MaxStartSize = 0.5f,

                MinEndSize = 2.5f,
                MaxEndSize = 5f,

                EmitterVelocitySensitivity = 1f,

                Transparent = true,
                Additive    = true
            };

            settings.Scale(scale);

            return(settings);
        }
        /// <summary>
        /// Adds a new particle system to the collection
        /// </summary>
        /// <param name="name">Particle system name</param>
        /// <param name="type">Particle system type</param>
        /// <param name="description">Particle system description</param>
        /// <param name="emitter">Particle emitter</param>
        /// <returns>Returns the new particle system</returns>
        public IParticleSystem AddParticleSystem(string name, ParticleSystemTypes type, ParticleSystemDescription description, ParticleEmitter emitter)
        {
            IParticleSystem pSystem = null;

            if (type == ParticleSystemTypes.CPU)
            {
                pSystem = new ParticleSystemCpu(this.Game, name, description, emitter);
            }
            else if (type == ParticleSystemTypes.GPU)
            {
                pSystem = new ParticleSystemGpu(this.Game, name, description, emitter);
            }
            else
            {
                throw new EngineException("Bad particle system type");
            }

            this.AllocatedParticleCount += pSystem.MaxConcurrentParticles;

            this.ParticleSystems.Add(pSystem);

            return(pSystem);
        }
 /// <summary>
 /// Adds a new particle system to the collection
 /// </summary>
 /// <param name="type">Particle system type</param>
 /// <param name="description">Particle system description</param>
 /// <param name="emitter">Particle emitter</param>
 /// <returns>Returns the new particle system</returns>
 public IParticleSystem AddParticleSystem(ParticleSystemTypes type, ParticleSystemDescription description, ParticleEmitter emitter)
 {
     return(this.AddParticleSystem(null, type, description, emitter));
 }
 /// <summary>
 /// Creates a new particle description from another one
 /// </summary>
 /// <param name="particleDesc">The other particle description</param>
 /// <param name="scale">Scale</param>
 /// <returns>Returns the new generated particle system description</returns>
 internal static ParticleSystemDescription Initialize(ParticleSystemDescription particleDesc, float scale = 1f)
 {
     return(Initialize(particleDesc.ParticleType, particleDesc.ContentPath, particleDesc.TextureName, scale));
 }