/// <summary>
        /// Only for some testing values
        /// </summary>
        public void InitDefault()
        {
            Birth.AddKey(0, 1.0f);
            Life.AddKey(0, 10.0f);
            Thickness.AddKey(0, 1.0f);
            Velocity.AddKey(0, new Vector3(0, 1, 0));


            MyAnimatedPropertyVector4 colorKey = new MyAnimatedPropertyVector4(Color.Name);

            colorKey.AddKey(0, new Vector4(1, 0, 0, 1));
            colorKey.AddKey(1, new Vector4(0, 0, 1, 1));
            Color.AddKey(0, colorKey);

            MyAnimatedPropertyFloat radiusKey = new MyAnimatedPropertyFloat(Radius.Name);

            radiusKey.AddKey(0, 1.0f);
            Radius.AddKey(0, radiusKey);

            MyAnimatedPropertyTransparentMaterial materialKey = new MyAnimatedPropertyTransparentMaterial(Material.Name);

            materialKey.AddKey(0, MyTransparentMaterials.GetMaterial("Smoke"));
            Material.AddKey(0, materialKey);

            LODBirth.AddKey(0, 1.0f);
            LODRadius.AddKey(0, 1.0f);

            UseLayerSorting.SetValue(false);
            SortLayer.SetValue(-1);
        }
        public void InitDefault()
        {
            Birth.AddKey(0, 1.0f);
            Life.AddKey(0, 10.0f);
            Thickness.AddKey(0, 1.0f);
            Velocity.AddKey(0, new Vector3(0, 1, 0));


            MyAnimatedPropertyVector4 colorKey = new MyAnimatedPropertyVector4(Color.Name);

            colorKey.AddKey(0, new Vector4(1, 0, 0, 1));
            colorKey.AddKey(1, new Vector4(0, 0, 1, 1));
            Color.AddKey(0, colorKey);

            MyAnimatedPropertyFloat radiusKey = new MyAnimatedPropertyFloat(Radius.Name);

            radiusKey.AddKey(0, 1.0f);
            Radius.AddKey(0, radiusKey);

            MyAnimatedPropertyTransparentMaterial materialKey = new MyAnimatedPropertyTransparentMaterial(Material.Name);

            materialKey.AddKey(0, MyTransparentMaterials.GetMaterial("Smoke"));
            Material.AddKey(0, materialKey);

            LODBirth.AddKey(0, 1.0f);
            LODBirth.AddKey(MyConstants.MAX_PARTICLE_DISTANCE_DEFAULT, 0f);
            LODRadius.AddKey(0, 1.0f);

            PivotDistVar.SetValue(1.0f);

            AccelerationVar.SetValue(0.0f);

            UseLayerSorting.SetValue(false);
            SortLayer.SetValue(-1);
        }
        private void UpdateParticlesCreation()
        {
            if (!Enabled.GetValue <bool>())
            {
                return;
            }

            //particles to create in this update
            if (!m_effect.IsStopped)
            {
                float lodBirth = 1.0f;
                if (GetEffect().EnableLods)
                {
                    LODBirth.GetInterpolatedValue <float>(GetEffect().Distance, out lodBirth);
                }

                Birth.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out m_birthRate);
                m_birthRate *=
                    MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS
                    * (EnableCustomBirth ? m_effect.UserBirthMultiplier : 1.0f)
                    * MyParticlesManager.BirthMultiplierOverall
                    * lodBirth;

                m_particlesToCreate += m_birthRate;
            }

            //If speed of effect is too high, there would be created bunches
            //of particles each frame. By interpolating position, we create
            //seamless particle creation.
            Vector3 positionDelta = Vector3.Zero;

            if (!m_lastEffectPosition.HasValue)
            {
                m_lastEffectPosition = EffectMatrix.Translation;
            }

            //Position delta interpolates particle position at fast flying objects, dont do that while motion inheritance
            if (m_particlesToCreate > 1.0f && !m_effect.CalculateDeltaMatrix)
            {
                positionDelta = (EffectMatrix.Translation - m_lastEffectPosition.Value) / (int)m_particlesToCreate;
            }

            //VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("CreateParticle");


            using (ParticlesLock.AcquireExclusiveUsing())
            {
                int maxParticles = 40;
                while (m_particlesToCreate >= 1.0f && maxParticles-- > 0)
                {
                    if (m_effect.CalculateDeltaMatrix)
                    {
                        CreateParticle(EffectMatrix.Translation);
                    }
                    else
                    {
                        CreateParticle(m_lastEffectPosition.Value + positionDelta * (int)m_particlesToCreate);
                    }

                    m_particlesToCreate -= 1.0f;
                }
            }

            //   VRageRender.MyRenderProxy.GetRenderProfiler().StartNextBlock("OnLife");

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

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

                    float particlesToCreate = inheritedGeneration.m_particlesToCreate;

                    using (ParticlesLock.AcquireSharedUsing())
                    {
                        foreach (MyAnimatedParticle particle in m_particles)
                        {
                            inheritedGeneration.m_particlesToCreate = particlesToCreate;
                            inheritedGeneration.EffectMatrix        = MatrixD.CreateWorld(particle.ActualPosition, (Vector3D)particle.Velocity, Vector3D.Cross(Vector3D.Left, particle.Velocity));
                            inheritedGeneration.UpdateParticlesCreation();
                        }
                    }
                }
            }

            //  VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            m_lastEffectPosition = EffectMatrix.Translation;
        }
        public void Init()
        {
            System.Diagnostics.Debug.Assert(Birth == null);

            AddProperty(MyGenerationPropertiesEnum.Birth, new MyAnimatedPropertyFloat("Birth"));
            AddProperty(MyGenerationPropertiesEnum.BirthVar, new MyConstPropertyFloat("Birth var"));

            AddProperty(MyGenerationPropertiesEnum.Life, new MyAnimatedPropertyFloat("Life"));
            AddProperty(MyGenerationPropertiesEnum.LifeVar, new MyConstPropertyFloat("Life var"));

            AddProperty(MyGenerationPropertiesEnum.Velocity, new MyAnimatedPropertyVector3("Velocity"));
            AddProperty(MyGenerationPropertiesEnum.VelocityDir, new MyConstPropertyEnum("Velocity dir", typeof(MyVelocityDirEnum), s_velocityDirStrings));

            AddProperty(MyGenerationPropertiesEnum.Angle, new MyAnimatedPropertyFloat("Angle"));
            AddProperty(MyGenerationPropertiesEnum.AngleVar, new MyConstPropertyFloat("Angle var"));

            AddProperty(MyGenerationPropertiesEnum.RotationSpeed, new MyAnimatedPropertyFloat("Rotation speed"));
            AddProperty(MyGenerationPropertiesEnum.RotationSpeedVar, new MyConstPropertyFloat("Rotation speed var"));

            AddProperty(MyGenerationPropertiesEnum.Radius, new MyAnimatedProperty2DFloat("Radius"));
            AddProperty(MyGenerationPropertiesEnum.RadiusVar, new MyAnimatedPropertyFloat("Radius var"));

            AddProperty(MyGenerationPropertiesEnum.Color, new MyAnimatedProperty2DVector4("Color"));
            AddProperty(MyGenerationPropertiesEnum.ColorVar, new MyAnimatedPropertyFloat("Color var"));

            AddProperty(MyGenerationPropertiesEnum.Material, new MyAnimatedProperty2DTransparentMaterial("Material", MyTransparentMaterialInterpolator.Switch));

            AddProperty(MyGenerationPropertiesEnum.ParticleType, new MyConstPropertyEnum("Particle type", typeof(MyParticleTypeEnum), s_particleTypeStrings));

            AddProperty(MyGenerationPropertiesEnum.Thickness, new MyAnimatedPropertyFloat("Thickness"));

            AddProperty(MyGenerationPropertiesEnum.Enabled, new MyConstPropertyBool("Enabled"));
            Enabled.SetValue(true);

            AddProperty(MyGenerationPropertiesEnum.BlendTextures, new MyConstPropertyBool("Blend textures"));
            BlendTextures.SetValue(true);

            AddProperty(MyGenerationPropertiesEnum.EnableCustomRadius, new MyConstPropertyBool("Enable custom radius"));
            AddProperty(MyGenerationPropertiesEnum.EnableCustomVelocity, new MyConstPropertyBool("Enable custom velocity"));
            AddProperty(MyGenerationPropertiesEnum.EnableCustomBirth, new MyConstPropertyBool("Enable custom birth"));

            AddProperty(MyGenerationPropertiesEnum.OnDie, new MyConstPropertyGenerationIndex("OnDie"));
            OnDie.SetValue(-1);
            AddProperty(MyGenerationPropertiesEnum.OnLife, new MyConstPropertyGenerationIndex("OnLife"));
            OnLife.SetValue(-1);

            AddProperty(MyGenerationPropertiesEnum.LODBirth, new MyAnimatedPropertyFloat("LODBirth"));
            AddProperty(MyGenerationPropertiesEnum.LODRadius, new MyAnimatedPropertyFloat("LODRadius"));

            AddProperty(MyGenerationPropertiesEnum.MotionInheritance, new MyAnimatedPropertyFloat("Motion inheritance"));

            AddProperty(MyGenerationPropertiesEnum.UseLayerSorting, new MyConstPropertyBool("Use layer sorting"));
            AddProperty(MyGenerationPropertiesEnum.SortLayer, new MyConstPropertyInt("Sort layer"));
            AddProperty(MyGenerationPropertiesEnum.AlphaAnisotropic, new MyConstPropertyBool("Alpha anisotropic"));

            AddProperty(MyGenerationPropertiesEnum.Gravity, new MyConstPropertyFloat("Gravity"));

            Thickness.AddKey(0, 1.0f);

            LODBirth.AddKey(0, 1.0f);
            LODRadius.AddKey(0, 1.0f);

            UseLayerSorting.SetValue(false);
            SortLayer.SetValue(-1);

            m_emitter.Init();
        }
        public void Deserialize(XmlReader reader)
        {
            m_name = reader.GetAttribute("name");
            int version = Convert.ToInt32(reader.GetAttribute("version"), CultureInfo.InvariantCulture);

            reader.ReadStartElement(); //ParticleGeneration

            foreach (IMyConstProperty property in m_properties)
            {
                if (reader.Name == "Emitter")
                {
                    break; //we added new property which is not in xml yet
                }
                property.Deserialize(reader);
            }

            reader.ReadStartElement();
            m_emitter.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadEndElement(); //ParticleGeneration

            //Disable texture blending if it is set but unneccessary
            if (BlendTextures)
            {
                bool someMaterialKeysDifferent = false;
                for (int j = 0; j < Material.GetKeysCount(); j++)
                {
                    MyAnimatedPropertyTransparentMaterial key;
                    float time;
                    Material.GetKey(j, out time, out key);

                    MyTransparentMaterial previousMaterial = null;
                    for (int i = 0; i < key.GetKeysCount(); i++)
                    {
                        float timeMat;
                        MyTransparentMaterial material;
                        key.GetKey(i, out timeMat, out material);

                        if (previousMaterial != null && (previousMaterial != material))
                        {
                            if (previousMaterial.Texture != material.Texture)
                            {
                                someMaterialKeysDifferent = true;
                                break;
                            }
                        }
                        previousMaterial = material;
                    }

                    if (someMaterialKeysDifferent)
                    {
                        break;
                    }
                }

                if (!someMaterialKeysDifferent)
                {
                    BlendTextures.SetValue(false);
                }
            }
            float dist;
            float val;

            LODBirth.GetKey(LODBirth.GetKeysCount() - 1, out dist, out val);
            if (val > 0f)
            {
                LODBirth.AddKey(Math.Max(dist + MyConstants.MAX_PARTICLE_DISTANCE_EXTENSION, MyConstants.MAX_PARTICLE_DISTANCE_DEFAULT), 0f);
            }
        }