private void ResetParticle(ref Particle p) { if (this.disposed) { throw new ObjectDisposedException("ParticleSystemRenderer"); } if (!p.Alive) { p.Alive = true; p.Life = TimeSpan.FromMilliseconds(this.random.NextDouble() * (this.numParticles * InitTimeMultipler)).TotalMilliseconds; p.Position.X = 0; p.Position.Y = 0; p.Position.Z = 0; p.Velocity.X = 0; p.Velocity.Y = 0; p.Velocity.Z = 0; p.VelocityRotation = 0; p.Angle = 0; p.Size = 0; p.TimeLife = 0; } else { // Life if (this.settings.MinLife != this.settings.MaxLife) { TimeSpan time = TimeSpan.FromMilliseconds(MathHelper.Lerp( (float)this.settings.MinLife.TotalMilliseconds, (float)this.settings.MaxLife.TotalMilliseconds, (float)this.random.NextDouble())); p.TimeLife = time.TotalMilliseconds; } else { p.TimeLife = this.settings.MinLife.TotalMilliseconds; } p.Life = p.TimeLife; // Velocity if (this.settings.RandomVelocity != Vector3.Zero) { p.Velocity = this.settings.LocalVelocity; p.Velocity.X = p.Velocity.X + (this.settings.RandomVelocity.X * (((float)this.random.NextDouble() * 2) - 1)); p.Velocity.Y = p.Velocity.Y + (this.settings.RandomVelocity.Y * (((float)this.random.NextDouble() * 2) - 1)); p.Velocity.Z = p.Velocity.Z + (this.settings.RandomVelocity.Z * (((float)this.random.NextDouble() * 2) - 1)); } else { p.Velocity = this.settings.LocalVelocity; } p.Position = this.Transform.LocalWorld.Translation; if (this.settings.EmitterSize != Vector2.Zero) { switch (this.settings.EmitterShape) { case ParticleSystem3D.Shape.Circle: { float radius = this.settings.EmitterSize.X > this.settings.EmitterSize.Y ? (this.settings.EmitterSize.X / 2) : (this.settings.EmitterSize.Y / 2); double angle = this.random.NextDouble() * MathHelper.TwoPi; float x = (float)Math.Cos(angle); float y = (float)Math.Sin(angle); p.Position.X = p.Position.X + (x * radius); p.Position.Z = p.Position.Z + (y * radius); break; } case ParticleSystem3D.Shape.FillCircle: { float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float rnd1 = ((float)this.random.NextDouble() * 2) - 1; float radius = this.settings.EmitterSize.X > this.settings.EmitterSize.Y ? (this.settings.EmitterSize.X / 2) : (this.settings.EmitterSize.Y / 2); double angle = this.random.NextDouble() * MathHelper.TwoPi; float x = (float)Math.Cos(angle); float y = (float)Math.Sin(angle); p.Position.X = p.Position.X + (x * radius * rnd0); p.Position.Z = p.Position.Z + (y * radius * rnd1); break; } case ParticleSystem3D.Shape.Rectangle: { int c = this.random.Next(4); float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float xside = this.settings.EmitterSize.X / 2; float yside = this.settings.EmitterSize.Y / 2; switch (c) { case 0: p.Position.X = p.Position.X + xside; p.Position.Z = p.Position.Z + (yside * rnd0); break; case 1: p.Position.X = p.Position.X - xside; p.Position.Z = p.Position.Z + (yside * rnd0); break; case 2: p.Position.X = p.Position.X + (xside * rnd0); p.Position.Z = p.Position.Z + yside; break; case 3: default: p.Position.X = p.Position.X + (xside * rnd0); p.Position.Z = p.Position.Z - yside; break; } break; } case ParticleSystem3D.Shape.FillRectangle: { float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float rnd1 = ((float)this.random.NextDouble() * 2) - 1; p.Position.X = p.Position.X + ((this.settings.EmitterSize.X / 2) * rnd0); p.Position.Z = p.Position.Z + ((this.settings.EmitterSize.Y / 2) * rnd1); break; } default: { throw new ArgumentException("Invalid particleSystem shape"); } } } // Initial Angle if (this.settings.InitialAngle.Distinct(0)) { float randomAngle = ((float)this.random.NextDouble() * 2) - 1; p.Angle = this.settings.InitialAngle * randomAngle; } // Velocity Rotation if (this.settings.MinRotateSpeed.Distinct(this.settings.MaxRotateSpeed)) { p.VelocityRotation = MathHelper.Lerp(this.settings.MinRotateSpeed, this.settings.MaxRotateSpeed, (float)this.random.NextDouble()); } else { p.VelocityRotation = this.settings.MinRotateSpeed; } // Size if (this.settings.MinSize.Distinct(this.settings.MaxSize)) { p.Size = MathHelper.Lerp(this.settings.MinSize, this.settings.MaxSize, (float)this.random.NextDouble()); } else { p.Size = this.settings.MinSize; } // Color if (this.settings.MinColor != this.settings.MaxColor) { p.CurrentColor = Color.Lerp(ref this.settings.MinColor, ref this.settings.MaxColor, 1 - (float)this.random.NextDouble()); } else { p.CurrentColor = this.settings.MinColor; } p.Color = p.CurrentColor; Matrix.CreateFromYawPitchRoll(this.Transform.Rotation.Y, this.Transform.Rotation.X, this.Transform.Rotation.Z, out this.rotationMatrix); } }
/// <summary> /// Calculates the local world. /// </summary> /// <param name="p">The p.</param> /// <returns>World matrix.</returns> /// <exception cref="ObjectDisposedException">ParticleSystemRenderer has been disposed.</exception> private Matrix CalculateLocalWorld(ref Particle p) { if (this.disposed) { throw new ObjectDisposedException("ParticleSystemRenderer"); } // Optimización del código // Matrix matrix = Matrix.CreateRotationZ(p.Angle) // * Matrix.CreateScale(p.Size) // *Matrix.CreateBillboard(p.Position, RenderManager.Camera.Position, Vector3.Up, null); Matrix matrix; float cos = (float)Math.Cos(p.Angle); float sin = (float)Math.Sin(p.Angle); float scale = 0; if (this.settings.EndDeltaScale.Equal(1)) { scale = p.Size; } else { float age = 1 - (float)(p.Life / p.TimeLife); scale = p.Size * (1 + ((this.settings.EndDeltaScale - 1) * age)); } float cosscale = cos * scale; float sinscale = sin * scale; float negsinscale = -sin * scale; Vector3 cameraPosition = this.RenderManager.Camera.Position; Vector3 vector; Vector3 vector2; Vector3 vector3; vector.X = p.Position.X - cameraPosition.X; vector.Y = p.Position.Y - cameraPosition.Y; vector.Z = p.Position.Z - cameraPosition.Z; float num = vector.LengthSquared(); if (num < 0.0001f) { vector = Vector3.Forward; } else { Vector3.Multiply(ref vector, (float)(1f / ((float)Math.Sqrt((double)num))), out vector); } ////Vector3 cameraUpVector = Vector3.Up; // Vector3.Cross(ref cameraUpVector, ref vector, out vector3); vector3.X = vector.Z; vector3.Y = 0; vector3.Z = -vector.X; vector3.Normalize(); // Vector3.Cross(ref vector, ref vector3, out vector2); vector2.X = (vector.Y * vector3.Z) - (vector.Z * vector3.Y); vector2.Y = (vector.Z * vector3.X) - (vector.X * vector3.Z); vector2.Z = (vector.X * vector3.Y) - (vector.Y * vector3.X); matrix.M11 = (cosscale * vector3.X) + (sinscale * vector2.X); matrix.M12 = (cosscale * vector3.Y) + (sinscale * vector2.Y); matrix.M13 = (cosscale * vector3.Z) + (sinscale * vector2.Z); matrix.M14 = 0f; matrix.M21 = (negsinscale * vector3.X) + (cosscale * vector2.X); matrix.M22 = (negsinscale * vector3.Y) + (cosscale * vector2.Y); matrix.M23 = (negsinscale * vector3.Z) + (cosscale * vector2.Z); matrix.M24 = 0f; matrix.M31 = scale * vector.X; matrix.M32 = scale * vector.Y; matrix.M33 = scale * vector.Z; matrix.M34 = 0f; matrix.M41 = p.Position.X; matrix.M42 = p.Position.Y; matrix.M43 = p.Position.Z; matrix.M44 = 1f; return matrix; }
/// <summary> /// Calculates the local world. /// </summary> /// <param name="p">The p.</param> /// <returns>World matrix.</returns> /// <exception cref="ObjectDisposedException">ParticleSystemRenderer has been disposed.</exception> private Matrix CalculateLocalWorld(ref Particle p) { if (this.disposed) { throw new ObjectDisposedException("ParticleSystemRenderer"); } float cos = (float)Math.Cos(p.Angle); float sin = (float)Math.Sin(p.Angle); float scale; if (this.settings.EndDeltaScale.Equal(1)) { scale = p.Size; } else { float age = 1 - (float)(p.Life / p.TimeLife); scale = p.Size * (1 + ((this.settings.EndDeltaScale - 1) * age)); } float scaleCos = scale * cos; float scaleSin = scale * sin; Matrix matrix; matrix.M11 = scaleCos; matrix.M12 = scaleSin; matrix.M13 = 0; matrix.M14 = 0; matrix.M21 = -scaleSin; matrix.M22 = scaleCos; matrix.M23 = 0; matrix.M24 = 0; matrix.M31 = 0f; matrix.M32 = 0f; matrix.M33 = 1f; matrix.M34 = 0f; matrix.M41 = p.Position.X; matrix.M42 = p.Position.Y; matrix.M43 = p.Position.Z; matrix.M44 = 1f; return matrix; }
private void ResetParticle(ref Particle p) { if (this.disposed) { throw new ObjectDisposedException("ParticleSystemRenderer"); } this.emitedParticle = true; p.Alive = true; if (this.settings.MinLife != this.settings.MaxLife) { float pLife = MathHelper.Lerp( this.settings.MinLife, this.settings.MaxLife, (float)this.random.NextDouble()); p.TimeLife = pLife; } else { p.TimeLife = this.settings.MinLife; } p.Life = p.TimeLife; // Velocity if (this.settings.RandomVelocity != Vector2.Zero) { p.Velocity.X = this.settings.LocalVelocity.X + (this.settings.RandomVelocity.X * (((float)this.random.NextDouble() * 2) - 1)); p.Velocity.Y = this.settings.LocalVelocity.Y + (this.settings.RandomVelocity.Y * (((float)this.random.NextDouble() * 2) - 1)); } else { p.Velocity.X = this.settings.LocalVelocity.X; p.Velocity.Y = this.settings.LocalVelocity.Y; } p.Position = (this.Transform as Transform3D).Position; p.StartTime = DateTime.Now.Ticks; if (this.settings.EmitterSize != Vector3.Zero) { switch (this.settings.EmitterShape) { case ParticleSystem2D.Shape.Circle: { float radius = this.settings.EmitterSize.X > this.settings.EmitterSize.Y ? (this.settings.EmitterSize.X / 2) : (this.settings.EmitterSize.Y / 2); double angle = this.random.NextDouble() * MathHelper.TwoPi; float x = (float)Math.Cos(angle); float y = (float)Math.Sin(angle); p.Position.X = p.Position.X + (x * radius); p.Position.Y = p.Position.Y + (y * radius); break; } case ParticleSystem2D.Shape.FillCircle: { float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float rnd1 = ((float)this.random.NextDouble() * 2) - 1; float radius = this.settings.EmitterSize.X > this.settings.EmitterSize.Y ? (this.settings.EmitterSize.X / 2) : (this.settings.EmitterSize.Y / 2); double angle = this.random.NextDouble() * MathHelper.TwoPi; float x = (float)Math.Cos(angle); float y = (float)Math.Sin(angle); p.Position.X = p.Position.X + (x * radius * rnd0); p.Position.Y = p.Position.Y + (y * radius * rnd1); break; } case ParticleSystem2D.Shape.Rectangle: { int c = this.random.Next(4); float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float xside = this.settings.EmitterSize.X / 2; float yside = this.settings.EmitterSize.Y / 2; switch (c) { case 0: p.Position.X = p.Position.X + xside; p.Position.Y = p.Position.Y + (yside * rnd0); break; case 1: p.Position.X = p.Position.X - xside; p.Position.Y = p.Position.Y + (yside * rnd0); break; case 2: p.Position.X = p.Position.X + (xside * rnd0); p.Position.Y = p.Position.Y + yside; break; case 3: default: p.Position.X = p.Position.X + (xside * rnd0); p.Position.Y = p.Position.Y - yside; break; } break; } case ParticleSystem2D.Shape.FillRectangle: { float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float rnd1 = ((float)this.random.NextDouble() * 2) - 1; p.Position.X = p.Position.X + ((this.settings.EmitterSize.X / 2) * rnd0); p.Position.Y = p.Position.Y + ((this.settings.EmitterSize.Y / 2) * rnd1); break; } case ParticleSystem2D.Shape.FillBox: { float rnd0 = ((float)this.random.NextDouble() * 2) - 1; float rnd1 = ((float)this.random.NextDouble() * 2) - 1; float rnd2 = ((float)this.random.NextDouble() * 2) - 1; p.Position.X = p.Position.X + ((this.settings.EmitterSize.X / 2) * rnd0); p.Position.Y = p.Position.Y + ((this.settings.EmitterSize.Y / 2) * rnd1); p.Position.Z = p.Position.Z + ((this.settings.EmitterSize.Z / 2) * rnd1); break; } default: { throw new ArgumentException("Invalid particleSystem shape"); } } } // Initial Angle if (this.settings.InitialAngle.Distinct(0) || this.settings.InitialAngleVariation.Distinct(0)) { float randomAngle = this.settings.InitialAngleVariation * (((float)this.random.NextDouble() * 2) - 1); p.Angle = this.settings.InitialAngle + randomAngle; } // Velocity Rotation if (this.settings.MinRotateSpeed.Distinct(this.settings.MaxRotateSpeed)) { p.VelocityRotation = MathHelper.Lerp(this.settings.MinRotateSpeed, this.settings.MaxRotateSpeed, (float)this.random.NextDouble()); } else { p.VelocityRotation = this.settings.MinRotateSpeed; } // Size if (this.settings.MinSize.Distinct(this.settings.MaxSize)) { p.Size = MathHelper.Lerp(this.settings.MinSize, this.settings.MaxSize, (float)this.random.NextDouble()); } else { p.Size = this.settings.MinSize; } // Color if (this.settings.MinColor != this.settings.MaxColor) { p.CurrentColor = Color.Lerp(this.settings.MinColor, this.settings.MaxColor, 1 - (float)this.random.NextDouble()); } else { p.CurrentColor = this.settings.MinColor; } p.Color = p.CurrentColor; p.CurrentIndex = -1; Matrix.CreateFromYawPitchRoll(0, 0, this.Transform.Rotation, out this.rotationMatrix); }
/// <summary> /// Calculates the local world. /// </summary> /// <param name="p">The p.</param> /// <returns>World matrix.</returns> /// <exception cref="ObjectDisposedException">ParticleSystemRenderer has been disposed.</exception> private Matrix CalculateLocalWorld(ref Particle p) { if (this.disposed) { throw new ObjectDisposedException("ParticleSystemRenderer"); } ////Matrix matrix = Matrix.CreateRotationZ(p.Angle) //// * Matrix.CreateScale(p.Size) //// * Matrix.CreateTranslation(p.Position); float cos = (float)Math.Cos(p.Angle); float sin = (float)Math.Sin(p.Angle); float scale; if (this.settings.EndDeltaScale.Equal(1)) { scale = p.Size; } else { float age = 1 - (float)(p.Life / p.TimeLife); scale = p.Size * (1 + ((this.settings.EndDeltaScale - 1) * age)); } float scaleCos = scale * cos; float scaleSin = scale * sin; Matrix matrix; if (!this.viewportEnabled) { matrix.M11 = scaleCos; matrix.M12 = scaleSin; matrix.M13 = 0; matrix.M14 = 0; matrix.M21 = -scaleSin; matrix.M22 = scaleCos; matrix.M23 = 0; matrix.M24 = 0; matrix.M31 = 0f; matrix.M32 = 0f; matrix.M33 = 1f; matrix.M34 = 0f; matrix.M41 = p.Position.X; matrix.M42 = p.Position.Y; matrix.M43 = 0; matrix.M44 = 1f; } else { matrix.M11 = scaleCos * this.viewportScale.X; matrix.M12 = scaleSin * this.viewportScale.Y; matrix.M13 = 0; matrix.M14 = 0; matrix.M21 = -scaleSin * this.viewportScale.X; matrix.M22 = scaleCos * this.viewportScale.Y; matrix.M23 = 0; matrix.M24 = 0; matrix.M31 = 0f; matrix.M32 = 0f; matrix.M33 = 1f; matrix.M34 = 0f; matrix.M41 = (p.Position.X * this.viewportScale.X) + this.viewportTranslate.X; matrix.M42 = (p.Position.Y * this.viewportScale.Y) + this.viewportTranslate.Y; matrix.M43 = 0; matrix.M44 = 1f; } return matrix; }