/// <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); }