Example #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>
        /// Calculates the initial velocity for a particle
        /// </summary>
        /// <param name="parameters">Particle system parameters</param>
        /// <param name="hVelVariance">Horizontal velocity variance</param>
        /// <param name="vVelVariance">Vertical velocity variance</param>
        /// <param name="hAngleVariance">Horizontal angle variance</param>
        /// <returns>Returns the initial velocity vector with magnitude</returns>
        public Vector3 CalcInitialVelocity(ParticleSystemParams parameters, float hVelVariance, float vVelVariance, float hAngleVariance)
        {
            Vector3 velocity = this.Velocity * parameters.EmitterVelocitySensitivity;

            float horizontalVelocity = MathUtil.Lerp(
                parameters.HorizontalVelocity.X,
                parameters.HorizontalVelocity.Y,
                hVelVariance);

            float horizontalAngle = hAngleVariance * MathUtil.TwoPi;

            velocity.X += horizontalVelocity * (float)Math.Cos(horizontalAngle);
            velocity.Z += horizontalVelocity * (float)Math.Sin(horizontalAngle);

            velocity.Y += MathUtil.Lerp(
                parameters.VerticalVelocity.X,
                parameters.VerticalVelocity.Y,
                vVelVariance);

            return(velocity);
        }
        /// <summary>
        /// Samples a bounding box for the current emitter at the specified time
        /// </summary>
        /// <param name="emitter">Emitter</param>
        /// <param name="systemParams">Particle system parameters</param>
        /// <param name="time">Time</param>
        /// <returns>Returns the sampled bounding box</returns>
        private static BoundingBox SampleBBox(ParticleEmitter emitter, ParticleSystemParams systemParams, float time)
        {
            //Initial position
            Vector3 initialPos         = Vector3.Zero;
            Vector3 velocity           = emitter.Velocity * systemParams.EmitterVelocitySensitivity;
            float   horizontalVelocity = Math.Max(systemParams.HorizontalVelocity.X, systemParams.HorizontalVelocity.Y);

            //Max v velocity
            Vector3 vVelocity = velocity;

            vVelocity.Y *= Math.Max(systemParams.VerticalVelocity.X, systemParams.VerticalVelocity.Y);

            //Max h velocity
            Vector3 hVelocity1 = velocity;

            hVelocity1.X *= horizontalVelocity * (float)Math.Cos(0);
            hVelocity1.Z *= horizontalVelocity * (float)Math.Sin(0);

            Vector3 hVelocity2 = velocity;

            hVelocity2.X *= horizontalVelocity * (float)Math.Cos(1);
            hVelocity2.Z *= horizontalVelocity * (float)Math.Sin(1);

            //Final positions
            Vector3 finalPosV = ComputeParticlePosition(
                initialPos,
                vVelocity,
                systemParams.EndVelocity,
                systemParams.MaxDuration * time,
                time,
                systemParams.Gravity);

            Vector3 finalPosH1 = ComputeParticlePosition(
                initialPos,
                hVelocity1,
                systemParams.EndVelocity,
                systemParams.MaxDuration * time,
                time,
                systemParams.Gravity);

            Vector3 finalPosH2 = ComputeParticlePosition(
                initialPos,
                hVelocity2,
                systemParams.EndVelocity,
                systemParams.MaxDuration * time,
                time,
                systemParams.Gravity);

            float startSize = systemParams.MaxStartSize * 0.5f;

            BoundingSphere initial = new BoundingSphere(initialPos + new Vector3(0, startSize, 0), startSize * 0.5f);

            float endSize = systemParams.MaxEndSize * 0.5f;

            BoundingSphere finalV  = new BoundingSphere(finalPosV + new Vector3(0, endSize, 0), endSize * 0.5f);
            BoundingSphere finalH1 = new BoundingSphere(finalPosH1 + new Vector3(0, endSize, 0), endSize * 0.5f);
            BoundingSphere finalH2 = new BoundingSphere(finalPosH2 + new Vector3(0, endSize, 0), endSize * 0.5f);

            var bbox = BoundingBox.FromSphere(initial);

            bbox = BoundingBox.Merge(bbox, BoundingBox.FromSphere(finalV));
            bbox = BoundingBox.Merge(bbox, BoundingBox.FromSphere(finalH1));
            bbox = BoundingBox.Merge(bbox, BoundingBox.FromSphere(finalH2));

            return(bbox);
        }