예제 #1
0
 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);
 }
예제 #2
0
        /// <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;
        }
예제 #3
0
        /// <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;
        }
예제 #4
0
        /// <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;
                }
            }
        }
예제 #5
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)
        {
            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;
        }
예제 #6
0
 /// <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;
 }
예제 #7
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;
        }
예제 #8
0
 /// <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);
 }
예제 #9
0
 /// <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)
 {
 }
예제 #10
0
 /// <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);
예제 #11
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)
        {
            if (double.IsNaN(m_max))
                particle.Rotation = m_min;
            else
                particle.Rotation = Utils.RandomDouble(m_min, m_max);

            particle.Rotation += emitter.RotRadians;
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        /// <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;
        }
예제 #14
0
        /// <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;
        }
예제 #15
0
 /// <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);
 }
예제 #16
0
        /// <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;
        }
예제 #17
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;
        }
예제 #18
0
 /// <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)
 {
 }
예제 #19
0
        /// <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();
            }
        }
예제 #20
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)
        {
            //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());
        }
예제 #21
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)
        {
            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;
            }
        }
예제 #22
0
파일: Jet.cs 프로젝트: JuroGandalf/Ragnarok
 /// <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;
         }
     }
 }
예제 #23
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 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;
        }
예제 #24
0
        /// <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;
        }
예제 #25
0
 /// <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;
 }
예제 #26
0
        /// <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));
        }
예제 #27
0
        /// <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));
        }
예제 #28
0
        /// <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;
            }
        }
예제 #29
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)
        {
            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;
        }
예제 #30
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)
        {
            Point loc;
            loc = m_zone.GetLocation();
            particle.X = loc.X;
            particle.Y = loc.Y;

            particle.PreviousX = particle.X;
            particle.PreviousY = particle.Y;
        }