public override void Initialize(Emitter emitter, Particle particle) { if (double.IsNaN(m_max)) particle.Lifetime = m_min; else particle.Lifetime = Utils.RandomDouble(m_min, m_max); }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { double diffX = particle.TargetX - particle.X; double diffY = particle.TargetY - particle.Y; double len = Math.Sqrt(diffX * diffX + diffY * diffY); if (len < VelocityLength * 2 / 3) { particle.IsDead = true; return; } len /= VelocityLength; particle.X += diffX / len; particle.Y += diffY / len; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { if (particle.AngularVelocity == 0) return; double scale = 1 - m_friction * elapsedTime / particle.AngularVelocity; if (scale < 0) particle.AngularVelocity = 0; else particle.AngularVelocity *= scale; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { List<Particle> particles = emitter.Particles; Particle other; int i; int len = particles.Count; double dx; double dy; double vel = 0; int count = 0; double factor; for (i = particles.IndexOf(particle) - 1; i >= 0; i--) { other = particles[i]; if ((dx = particle.X - other.X) > m_min) break; dy = other.Y - particle.Y; if (dy > m_min || dy < -m_min) continue; vel += other.AngularVelocity; count++; } for (i = particles.IndexOf(particle) + 1; i < len; i++) { other = particles[i]; if ((dx = other.X - particle.X) > m_min) break; dy = other.Y - particle.Y; if (dy > m_min || dy < -m_min) continue; vel += other.AngularVelocity; count++; } if (count != 0) { vel = vel / count - particle.AngularVelocity; if (vel != 0) { double velSign = 1; if (vel < 0) { velSign = -1; vel = -vel; } factor = elapsedTime * m_acc; if (factor > vel) factor = vel; particle.AngularVelocity += factor * velSign; } } }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { Point loc; if (emitter.RotRadians == 0) { loc = m_zone.GetLocation(); particle.TargetX = loc.X; particle.TargetY = loc.Y; } else { double sin = Math.Sin(emitter.RotRadians); double cos = Math.Cos(emitter.RotRadians); loc = m_zone.GetLocation(); particle.TargetX = cos * loc.X - sin * loc.Y; particle.TargetY = cos * loc.Y + sin * loc.X; } particle.TargetX += emitter.X; particle.TargetY += emitter.Y; }
/// <summary> /// The startEmitter method is called when the emitter starts. /// </summary> /// <param name="emitter">The emitter</param> /// <returns>The number of particles the emitter should emit /// at the moment it starts.</returns> public uint StartEmitter(Emitter emitter) { NewTimeToNext(); return 0; }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { var brush = new ImageBrush() { ImageSource = m_image, }; Material material = (m_materialType == MaterialType.Emissive ? (Material)new EmissiveMaterial() { Brush = brush, } : new DiffuseMaterial() { Brush = brush, }); GeometryModel3D model = new GeometryModel3D() { Geometry = m_mesh, Material = material, }; particle.Brush = brush; particle.Material = material; particle.Model = model; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { particle.Rotation = Math.Atan2(particle.VelocityY, particle.VelocityX); }
/// <summary> /// The addedToEmitter method is called by the emitter when the Action is added to it /// It is called within the emitter's addAction method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that the Action was added to.</param> public virtual void AddedToEmitter(Emitter emitter) { }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public abstract void Update(Emitter emitter, Particle particle, double elapsedTime);
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { if (double.IsNaN(m_max)) particle.Rotation = m_min; else particle.Rotation = Utils.RandomDouble(m_min, m_max); particle.Rotation += emitter.RotRadians; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { m_lastTime += elapsedTime; if (m_lastTime > 1) { m_colorIndex++; m_lastTime = 0; } if (m_colorIndex > 360) m_colorIndex = 0; m_startColor = Utils.RotateHue((int)m_colorIndex, m_intensityStart); m_endColor = Utils.RotateHue((int)m_colorIndex, m_intensityEnd); particle.Color = Utils.InterpolateColors(m_startColor, m_endColor, particle.Energy); }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { double x = particle.X - m_x; double y = particle.Y - m_y; double dSq = x * x + y * y; if (dSq == 0) return; if (dSq < m_lowerBoundarySq || dSq > m_upperBoundarySq) return; double d = Math.Sqrt(dSq); double offset = d < m_radius ? m_depth - m_radius + d : m_depth - d + m_radius; double oldOffset = d < m_oldRadius ? m_depth - m_oldRadius + d : m_depth - d + m_oldRadius; offset *= m_invDepth; oldOffset *= m_invDepth; if (offset < 0) { elapsedTime = elapsedTime * (m_radiusChange + offset) / m_radiusChange; offset = 0; } if (oldOffset < 0) { elapsedTime = elapsedTime * (m_radiusChange + oldOffset) / m_radiusChange; oldOffset = 0; } double factor; if (d < m_oldRadius || d > m_radius) { factor = elapsedTime * m_power * (offset + oldOffset) / (m_radius * 2 * d); } else { double ratio = (1 - oldOffset) / m_radiusChange; double f1 = ratio * elapsedTime * m_power * (oldOffset + 1) / (m_radius * 2 * d); double f2 = (1 - ratio) * elapsedTime * m_power * (offset + 1) / (m_radius * 2 * d); factor = f1 + f2; } particle.VelocityX += x * factor; particle.VelocityY += y * factor; }
/// <summary> /// Called every frame before the particles are updated. This method is called via the FrameUpdateable /// public interface which is called by the emitter by using an UpdateOnFrame activity. /// </summary> public void FrameUpdate(Emitter emitter, double elapsedTime) { m_oldRadius = m_radius; m_radiusChange = m_expansionRate * elapsedTime; m_radius += m_radiusChange; double lowerBoundary = m_oldRadius - m_depth; if (lowerBoundary < 0) m_lowerBoundarySq = 0; else m_lowerBoundarySq = lowerBoundary * lowerBoundary; double upperBoundary = m_radius + m_depth; m_upperBoundarySq = upperBoundary * upperBoundary; }
/// <summary> /// The removedFromEmitter method is called by the emitter when the Action is removed from it /// It is called within the emitter's removeAction method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that the Action was removed from.</param> public override void RemovedFromEmitter(Emitter emitter) { if (m_updateActivity != null) emitter.Activities.Remove(m_updateActivity); }
/// <summary> /// The startEmitter method is called when the emitter starts. /// </summary> /// <param name="emitter">The emitter</param> /// <returns>The number of particles the emitter should emit /// at the moment it starts.</returns> public int StartEmitter(Emitter emitter) { m_lastTimeUpdate = 0; m_emitted = 0; return 0; }
/// <summary> /// The updateEmitter method is called every frame after the /// emitter has started. /// </summary> /// <param name="emitter">The emitter</param> /// <param name="elapsedTime">The time, in seconds, since the previous call to this method.</param> /// <returns>The number of particles the emitter should emit /// at this time.</returns> public int UpdateEmitter(Emitter emitter, double elapsedTime) { if (m_stop) return 0; m_lastTimeUpdate += elapsedTime; int count = (int)Math.Floor(m_rateMax * m_lastTimeUpdate + m_scale * (1 - Math.Cos(m_lastTimeUpdate * m_factor)) / m_factor); int ret = (int)(count - m_emitted); m_emitted = count; return ret; }
/// <summary> /// The removedFromEmitter method is called by the emitter when the Action is removed from it /// It is called within the emitter's removeAction method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that the Action was removed from.</param> public virtual void RemovedFromEmitter(Emitter emitter) { }
/// <summary> /// Initializes the image brush if need. /// </summary> public override void AddedToEmitter(Emitter emitter) { base.AddedToEmitter(emitter); if (m_image == null) { var uri = (m_imageUri.IsAbsoluteUri ? m_imageUri : new Uri(m_baseUri, m_imageUri)); m_image = GetImage(uri); m_mesh = Particle.CreateDefaultMesh(1.0, 1.0, m_image.Width, m_image.Height); m_mesh.Freeze(); } }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { //int colorRotation = Utils.Random.Next(360); //m_min = (uint)Utils.RotateHue(colorRotation, m_intensityStart).ToArgb(); //m_max = (uint)Utils.RotateHue(colorRotation, m_intensityEnd).ToArgb(); if (m_max == m_min) particle.Color = m_min; else particle.Color = Utils.InterpolateColors(m_min, m_max, Utils.Random.NextDouble()); }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { BitmapImage image = GetImage(); ImageBrush brush = new ImageBrush(image); if (IsSingle) { MaterialWrap materialWrap = new MaterialWrap() { MaterialType = MaterialType, Brush = brush, Color = Colors.White, }; Material material = materialWrap.Create(); GeometryModel3D model = new GeometryModel3D() { Geometry = Particle.CreateDefaultMesh(1.0, 1.0, image.Width, image.Height), Material = material, }; particle.Brush = brush; particle.Material = material; particle.Model = model; } else { // front MaterialWrap materialWrap1 = new MaterialWrap() { MaterialType = MaterialType, Brush = brush, Color = Colors.White, }; // back MaterialWrap materialWrap2 = new MaterialWrap() { MaterialType = MaterialType, Brush = brush, Color = Color.FromArgb(0xC0, 0xFF, 0xFF, 0xFF), }; Material material1 = materialWrap1.Create(); Material material2 = materialWrap2.Create(); MaterialGroup matGroup = new MaterialGroup(); matGroup.Children.Add(material2); matGroup.Children.Add(material1); GeometryModel3D model = new GeometryModel3D() { Geometry = Particle.CreateDefaultMesh(1.0, 1.0, image.Width, image.Height), Material = matGroup, }; particle.Brush = brush; particle.Material = material1; particle.Model = model; } }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { if (m_zone.Contains(particle.X, particle.Y)) { if (!m_invert) { particle.VelocityX += m_x * elapsedTime; particle.VelocityY += m_y * elapsedTime; } } else { if (m_invert) { particle.VelocityX += m_x * elapsedTime; particle.VelocityY += m_y * elapsedTime; } } }
/// <summary> /// The updateEmitter method is called every frame after the /// emitter has started. /// </summary> /// <param name="emitter">The emitter</param> /// <param name="elapsedTime">The time, in seconds, since the previous call to this method.</param> /// <returns>The number of particles the emitter should emit /// at this time.</returns> public uint UpdateEmitter(Emitter emitter, double elapsedTime) { if (m_stop) return 0; if (m_rate > m_rateMin && (m_timeToRateCheck -= elapsedTime) <= 0) { double t = Utils.Timer.RunningTime; m_times.Push(t); if (t > 9) { double frameRate = Math.Round(10000.0 / (t - m_times.Peek())); if (frameRate < m_target) { m_rate = Math.Floor((m_rate + m_rateMin) * 0.5); m_times.Clear(); if ((m_timeToRateCheck = emitter.Particles[0].Lifetime) == 0) m_timeToRateCheck = 2; } } } double emitTime = elapsedTime; uint count = 0; emitTime -= m_timeToNext; while (emitTime >= 0) { count++; NewTimeToNext(); emitTime -= m_timeToNext; } m_timeToNext = -emitTime; return count; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { double x = particle.X - Utils.MousePos.X; double y = particle.Y - Utils.MousePos.Y; double dSq = x * x + y * y; if (dSq == 0) return; double d = Math.Sqrt(dSq); if (dSq < m_epsilonSq) dSq = m_epsilonSq; double factor = (m_power * elapsedTime) / (dSq * d); particle.VelocityX += x * factor; particle.VelocityY += y * factor; }
/// <summary> /// The addedToEmitter method is called by the emitter when the Action is added to it /// It is called within the emitter's addAction method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that the Action was added to.</param> public override void AddedToEmitter(Emitter emitter) { emitter.SpaceSort = true; }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { bool turnLeft = ((particle.Y - Utils.MousePos.Y) * particle.VelocityX + (Utils.MousePos.X - particle.X) * particle.VelocityY > 0); double newAngle; if (turnLeft) newAngle = (Math.Atan2(particle.VelocityY, particle.VelocityX) + m_power * elapsedTime); else newAngle = (Math.Atan2(particle.VelocityY, particle.VelocityX) - m_power * elapsedTime); double len = Math.Sqrt(particle.VelocityX * particle.VelocityX + particle.VelocityY * particle.VelocityY); particle.VelocityX = (len * Math.Cos(newAngle)); particle.VelocityY = (len * Math.Sin(newAngle)); }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { double alpha = m_endAlpha + m_diffAlpha * particle.Energy; alpha = Math.Max(0.0, Math.Min(1.0, alpha)); particle.Color = (uint)((particle.Color & 0xFFFFFF) | ((uint)Math.Round(alpha * 255) << 24)); }
/// <summary> /// The update method is used by the emitter to apply the action /// to every particle. It is called within the emitter's update /// loop and need not be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be updated.</param> /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param> public override void Update(Emitter emitter, Particle particle, double elapsedTime) { double speedSq = particle.VelocityX * particle.VelocityX + particle.VelocityY * particle.VelocityY; if ((m_isMinimum && speedSq < m_limitSq) || (!m_isMinimum && speedSq > m_limitSq)) { double scale = (m_limit / Math.Sqrt(speedSq)); particle.VelocityX *= scale; particle.VelocityY *= scale; } }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { if (m_points == null) { if (m_zone == null) return; m_points = m_zone.GetLocationList().ToList(); } m_index = (m_index + 1) % m_points.Count; Point p = m_points[m_index]; particle.TargetX = p.X; particle.TargetY = p.Y; }
/// <summary> /// The initialize method is used by the emitter to initialize the particle. /// It is called within the emitter's createParticle method and need not /// be called by the user. /// </summary> /// <param name="emitter">The Emitter that created the particle.</param> /// <param name="particle">The particle to be initialized.</param> public override void Initialize(Emitter emitter, Particle particle) { Point loc; loc = m_zone.GetLocation(); particle.X = loc.X; particle.Y = loc.Y; particle.PreviousX = particle.X; particle.PreviousY = particle.Y; }