public void Clear()
        {
            using (ParticlesLock.AcquireExclusiveUsing())
            {
                int counter = 0;
                while (counter < m_particles.Count)
                {
                    MyAnimatedParticle particle = m_particles[counter];
                    m_particles.Remove(particle);
                    MyTransparentGeometry.DeallocateAnimatedParticle(particle);
                }
            }

            m_particlesToCreate  = 0;
            m_lastEffectPosition = m_effect.WorldMatrix.Translation;
        }
        private void CreateParticle(Vector3 interpolatedEffectPosition)
        {
            MyAnimatedParticle particle = MyTransparentGeometry.AddAnimatedParticle();

            if (particle == null)
            {
                return;
            }

            particle.Type = (MyParticleTypeEnum)ParticleType.GetValue <int>();

            MyUtils.AssertIsValid(m_effect.WorldMatrix);

            Vector3 startOffset;

            m_emitter.CalculateStartPosition(m_effect.GetElapsedTime(), Matrix.CreateWorld(interpolatedEffectPosition, m_effect.WorldMatrix.Forward, m_effect.WorldMatrix.Up), m_effect.UserEmitterScale * m_effect.UserScale, out startOffset, out particle.StartPosition);
            //particle.StartPosition = m_emitter.CalculateStartPosition(m_effect.GetElapsedTime(), m_effect.WorldMatrix, m_effect.UserEmitterScale, out startOffset);

            Vector3 particlePosition = particle.StartPosition;

            m_AABB = m_AABB.Include(ref particlePosition);

            Life.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Life);
            float lifeVar = LifeVar;

            if (lifeVar > 0)
            {
                particle.Life = MathHelper.Max(MyMwcUtils.GetRandomFloat(particle.Life - lifeVar, particle.Life + lifeVar), 0.1f);
            }

            Velocity.GetInterpolatedValue <Vector3>(m_effect.GetElapsedTime(), out particle.Velocity);
            particle.Velocity.X *= m_effect.UserScale;
            particle.Velocity.Y *= m_effect.UserScale;
            particle.Velocity.Z *= m_effect.UserScale;

            if (VelocityDir == MyVelocityDirEnum.FromEmitterCenter)
            {
                if (!MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.IsZero(startOffset - particle.StartPosition))
                {
                    float length = particle.Velocity.Length();
                    particle.Velocity = MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.Normalize(particle.StartPosition - startOffset) * length;
                }
            }
            particle.Velocity = Vector3.TransformNormal(particle.Velocity, GetEffect().WorldMatrix);

            Angle.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Angle);
            float angleVar = AngleVar;

            if (angleVar > 0)
            {
                particle.Angle = MyMwcUtils.GetRandomFloat(particle.Angle - AngleVar, particle.Angle + AngleVar);
            }

            RotationSpeed.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.RotationSpeed);
            float rotationSpeedVar = RotationSpeedVar;

            if (rotationSpeedVar > 0)
            {
                particle.RotationSpeed = MyMwcUtils.GetRandomFloat(particle.RotationSpeed - RotationSpeedVar, particle.RotationSpeed + RotationSpeedVar);
            }

            float radiusVar;

            RadiusVar.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out radiusVar);
            float lodRadius = 1.0f;

            if (GetEffect().EnableLods)
            {
                LODRadius.GetInterpolatedValue <float>(GetEffect().Distance, out lodRadius);
            }

            Radius.GetInterpolatedKeys(m_effect.GetElapsedTime(),
                                       radiusVar,
                                       (EnableCustomRadius.GetValue <bool>() ? m_effect.UserRadiusMultiplier : 1.0f)
                                       * lodRadius
                                       * GetEffect().UserScale,
                                       particle.Radius);

            if (particle.Type != MyParticleTypeEnum.Point)
            {
                Thickness.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Thickness);
            }

            float colorVar;

            ColorVar.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out colorVar);
            Color.GetInterpolatedKeys(m_effect.GetElapsedTime(), colorVar, 1.0f, particle.Color);

            Material.GetInterpolatedKeys(m_effect.GetElapsedTime(), 0, 1.0f, particle.Material);

            particle.Flags  = 0;
            particle.Flags |= BlendTextures.GetValue <bool>() ? MyAnimatedParticle.ParticleFlags.BlendTextures : 0;
            particle.Flags |= GetEffect().IsInFrustum ? MyAnimatedParticle.ParticleFlags.IsInFrustum : 0;

            particle.Start(this);

            m_particles.Add(particle);
        }
        private void UpdateParticlesLife()
        {
            int counter = 0;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-UpdateParticlesLife");

            MyParticleGeneration inheritedGeneration = null;
            Vector3 previousParticlePosition         = m_effect.WorldMatrix.Translation;
            float   particlesToCreate = 0;

            m_AABB = m_AABB.CreateInvalid();
            m_AABB = m_AABB.Include(ref previousParticlePosition);

            if (OnDie.GetValue <int>() != -1)
            {
                inheritedGeneration = GetInheritedGeneration(OnDie.GetValue <int>());

                if (inheritedGeneration == null)
                {
                    OnDie.SetValue(-1);
                }
                else
                {
                    inheritedGeneration.IsInherited = true;
                    particlesToCreate = inheritedGeneration.m_particlesToCreate;
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-Update01");

            Vector3 previousTrail0 = previousParticlePosition;
            Vector3 previousTrail1 = previousParticlePosition;

            using (ParticlesLock.AcquireExclusiveUsing())
            {
                while (counter < m_particles.Count)
                {
                    float motionInheritance;
                    MotionInheritance.GetInterpolatedValue(m_effect.GetElapsedTime(), out motionInheritance);

                    MyAnimatedParticle particle = m_particles[counter];

                    if (motionInheritance > 0)
                    {
                        m_effect.CalculateDeltaMatrix = true;
                    }

                    if (particle.Update())
                    {
                        if (motionInheritance > 0)
                        {
                            particle.AddMotionInheritance(ref motionInheritance, ref m_effect.DeltaMatrix);
                        }

                        if (counter == 0)
                        {
                            previousParticlePosition = particle.ActualPosition;
                            previousTrail0           = particle.Quad.Point1;
                            previousTrail1           = particle.Quad.Point2;
                            particle.Quad.Point0     = particle.ActualPosition;
                            particle.Quad.Point2     = particle.ActualPosition;
                        }

                        counter++;


                        if (particle.Type == MyParticleTypeEnum.Trail)
                        {
                            if (particle.ActualPosition == previousParticlePosition)
                            {
                                particle.Quad.Point0 = particle.ActualPosition;
                                particle.Quad.Point1 = particle.ActualPosition;
                                particle.Quad.Point2 = particle.ActualPosition;
                                particle.Quad.Point3 = particle.ActualPosition;
                            }
                            else
                            {
                                MyPolyLine polyLine = new MyPolyLine();
                                polyLine.Thickness = particle.Thickness;
                                polyLine.Point0    = particle.ActualPosition;
                                polyLine.Point1    = previousParticlePosition;

                                Vector3 direction           = polyLine.Point1 - polyLine.Point0;
                                Vector3 normalizedDirection = MyMwcUtils.Normalize(polyLine.Point1 - polyLine.Point0);


                                polyLine.Point1 = polyLine.Point0 + (polyLine.Point1 - polyLine.Point0);

                                polyLine.LineDirectionNormalized = normalizedDirection;
                                MyUtils.GetPolyLineQuad(out particle.Quad, ref polyLine);

                                particle.Quad.Point0 = previousTrail0 + direction * 0.15f;
                                particle.Quad.Point3 = previousTrail1 + direction * 0.15f;
                                previousTrail0       = particle.Quad.Point1;
                                previousTrail1       = particle.Quad.Point2;
                            }
                        }

                        previousParticlePosition = particle.ActualPosition;

                        m_AABB         = m_AABB.Include(ref previousParticlePosition);
                        particle.Flags = GetEffect().IsInFrustum ? particle.Flags | MyAnimatedParticle.ParticleFlags.IsInFrustum : particle.Flags & ~MyAnimatedParticle.ParticleFlags.IsInFrustum;
                        continue;
                    }

                    if (inheritedGeneration != null)
                    {
                        inheritedGeneration.m_particlesToCreate = particlesToCreate;
                        inheritedGeneration.EffectMatrix        = Matrix.CreateWorld(particle.ActualPosition, Vector3.Normalize(particle.Velocity), Vector3.Cross(Vector3.Left, particle.Velocity));
                        inheritedGeneration.UpdateParticlesCreation();
                    }

                    m_particles.Remove(particle);
                    MyTransparentGeometry.DeallocateAnimatedParticle(particle);
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }