Ejemplo n.º 1
0
        public void Start(MyParticleGeneration generation)
        {
            System.Diagnostics.Debug.Assert(Life > 0);

            m_elapsedTime        = 0;
            m_normalizedTime     = 0.0f;
            m_elapsedTimeDivider = VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS / Life;
            m_generation         = generation;

            MyUtils.AssertIsValid(StartPosition);
            MyUtils.AssertIsValid(Angle);
            MyUtils.AssertIsValid(Velocity);
            MyUtils.AssertIsValid(RotationSpeed);

            m_actualPosition   = StartPosition;
            m_previousPosition = m_actualPosition;
            m_actualAngle      = Angle;

            if (PivotRotation != null && PivotDistance != null)
            {
                Vector3 rotation;
                float   distance;
                PivotRotation.GetInterpolatedValue <Vector3>(0, out rotation);
                PivotDistance.GetInterpolatedValue <float>(0, out distance);
                Quaternion rotationQ = Quaternion.CreateFromYawPitchRoll(MathHelper.ToRadians(rotation.Y), MathHelper.ToRadians(rotation.X), MathHelper.ToRadians(rotation.Z));
                m_actualPivot = Vector3.Transform(Vector3.Forward, rotationQ) * distance;
            }
        }
        //  For sorting generations if needed
        public int CompareTo(object compareToObject)
        {
            MyParticleGeneration compareToGeneration = (MyParticleGeneration)compareToObject;

            if (UseLayerSorting && compareToGeneration.UseLayerSorting)
            {
                return(SortLayer.GetValue <int>().CompareTo(compareToGeneration.SortLayer.GetValue <int>()));
            }

            return(0);
        }
Ejemplo n.º 3
0
        public void AddGeneration(MyParticleGeneration generation)
        {
            m_generations.Add(generation);

            if (m_instances != null)
            {
                foreach (MyParticleEffect effect in m_instances)
                {
                    effect.AddGeneration(generation.CreateInstance(effect));
                }
            }
        }
        public MyParticleGeneration Duplicate(MyParticleEffect effect)
        {
            MyParticleGeneration generation = MyParticlesManager.GenerationsPool.Allocate();

            generation.Start(effect);

            generation.Name = Name;

            for (int i = 0; i < m_properties.Length; i++)
            {
                generation.m_properties[i] = m_properties[i].Duplicate();
            }

            m_emitter.Duplicate(generation.m_emitter);

            return(generation);
        }
Ejemplo n.º 5
0
        public void RemoveGeneration(int index)
        {
            MyParticleGeneration generation = m_generations[index];

            m_generations.Remove(generation);

            generation.Close();
            MyParticlesManager.GenerationsPool.Deallocate(generation);

            if (m_instances != null)
            {
                foreach (MyParticleEffect effect in m_instances)
                {
                    effect.RemoveGeneration(index);
                }
            }
        }
Ejemplo n.º 6
0
        public MyParticleEffect Duplicate()
        {
            MyParticleEffect effect = MyParticlesManager.EffectsPool.Allocate();

            effect.Start(0);

            effect.Name      = Name;
            effect.m_preload = m_preload;
            effect.m_length  = m_length;

            foreach (MyParticleGeneration generation in m_generations)
            {
                MyParticleGeneration duplicatedGeneration = generation.Duplicate(effect);
                effect.AddGeneration(duplicatedGeneration);
            }

            return(effect);
        }
Ejemplo n.º 7
0
        public void Start(MyParticleGeneration generation)
        {
            System.Diagnostics.Debug.Assert(Life > 0);

            m_elapsedTime        = 0;
            m_normalizedTime     = 0.0f;
            m_elapsedTimeDivider = VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS / Life;
            m_generation         = generation;

            MyUtils.AssertIsValid(StartPosition);
            MyUtils.AssertIsValid(Angle);
            MyUtils.AssertIsValid(Velocity);

            m_actualPosition   = StartPosition;
            m_previousPosition = m_actualPosition;
            m_actualAngle      = new Vector3(MathHelper.ToRadians(Angle.X), MathHelper.ToRadians(Angle.Y), MathHelper.ToRadians(Angle.Z));

            if (Pivot != null)
            {
                Pivot.GetInterpolatedValue <Vector3>(0, out m_actualPivot);
            }

            if (PivotRotation != null)
            {
                PivotRotation.GetInterpolatedValue <Vector3>(0, out m_actualPivotRotation);
            }

            m_arrayIndex = -1;
            if (ArrayIndex != null)
            {
                ArrayIndex.GetInterpolatedValue <int>(m_normalizedTime, out m_arrayIndex);

                int     arrayOffset = m_generation.ArrayOffset;
                Vector3 arraySize   = m_generation.ArraySize;

                if (arraySize.X > 0 && arraySize.Y > 0)
                {
                    int arrayModulo = m_generation.ArrayModulo == 0 ? (int)arraySize.X * (int)arraySize.Y : m_generation.ArrayModulo;
                    m_arrayIndex = arrayOffset + m_arrayIndex % arrayModulo;
                }
            }
        }
Ejemplo n.º 8
0
        public MyParticleEffect CreateInstance()
        {
            MyParticleEffect effect = MyParticlesManager.EffectsPool.Allocate(true);

            if (effect != null)
            {
                effect.Start(m_particleID);

                effect.Name    = Name;
                effect.Enabled = Enabled;
                effect.SetLength(GetLength());
                effect.SetPreload(GetPreload());
                effect.LowRes = LowRes;

                foreach (MyParticleGeneration generation in m_generations)
                {
                    MyParticleGeneration gen = generation.CreateInstance(effect);
                    if (gen != null)
                    {
                        effect.AddGeneration(gen);
                    }
                }

                foreach (MyParticleLight particleLight in m_particleLights)
                {
                    MyParticleLight pl = particleLight.CreateInstance(effect);
                    if (pl != null)
                    {
                        effect.AddParticleLight(pl);
                    }
                }

                if (m_instances == null)
                {
                    m_instances = new List <MyParticleEffect>();
                }

                m_instances.Add(effect);
            }

            return(effect);
        }
        public MyParticleGeneration CreateInstance(MyParticleEffect effect)
        {
            MyParticleGeneration generation = MyParticlesManager.GenerationsPool.Allocate(true);

            if (generation == null)
            {
                return(null);
            }

            generation.Start(effect);

            generation.Name = Name;

            for (int i = 0; i < m_properties.Length; i++)
            {
                generation.m_properties[i] = m_properties[i];
            }

            generation.m_emitter.CreateInstance(m_emitter);

            return(generation);
        }
Ejemplo n.º 10
0
        public void Deserialize(XmlReader reader)
        {
            m_name = reader.GetAttribute("name");
            int version = Convert.ToInt32(reader.GetAttribute("version"), CultureInfo.InvariantCulture);

            reader.ReadStartElement(); //ParticleEffect

            m_particleID = reader.ReadElementContentAsInt();

            m_length = reader.ReadElementContentAsFloat();

            m_preload = reader.ReadElementContentAsFloat();

            if (reader.Name == "LowRes")
            {
                LowRes = reader.ReadElementContentAsBoolean();
            }

            bool isEmpty = reader.IsEmptyElement;

            reader.ReadStartElement(); //Generations

            while (reader.NodeType != XmlNodeType.EndElement)
            {
                if (isEmpty)
                {
                    break;
                }

                if (reader.Name == "ParticleGeneration")
                {
                    MyParticleGeneration generation = MyParticlesManager.GenerationsPool.Allocate();
                    generation.Start(this);
                    generation.Init();

                    generation.Deserialize(reader);

                    AddGeneration(generation);
                }
                else
                if (reader.Name == "ParticleGPUGeneration")
                {
                    MyParticleGPUGeneration generation = MyParticlesManager.GPUGenerationsPool.Allocate();
                    generation.Start(this);
                    generation.Init();

                    generation.Deserialize(reader);

                    AddGeneration(generation);
                }
            }

            if (!isEmpty)
            {
                reader.ReadEndElement(); //Generations
            }
            if (reader.NodeType != XmlNodeType.EndElement)
            {
                isEmpty = reader.IsEmptyElement;
                if (isEmpty)
                {
                    reader.Read();
                }
                else
                {
                    reader.ReadStartElement(); //Particle lights

                    while (reader.NodeType != XmlNodeType.EndElement)
                    {
                        MyParticleLight particleLight = MyParticlesManager.LightsPool.Allocate();
                        particleLight.Start(this);
                        particleLight.Init();

                        particleLight.Deserialize(reader);

                        AddParticleLight(particleLight);
                    }

                    reader.ReadEndElement(); //Particle lights
                }
            }

            if (reader.NodeType != XmlNodeType.EndElement)
            {
                isEmpty = reader.IsEmptyElement;
                if (isEmpty)
                {
                    reader.Read();
                }
                else
                {
                    reader.ReadStartElement(); //Particle sounds

                    while (reader.NodeType != XmlNodeType.EndElement)
                    {
                        MyParticleSound particleSound = MyParticlesManager.SoundsPool.Allocate();
                        particleSound.Start(this);
                        particleSound.Init();

                        particleSound.Deserialize(reader);

                        AddParticleSound(particleSound);
                    }

                    reader.ReadEndElement(); //Particle sounds
                }
            }

            reader.ReadEndElement(); //ParticleEffect
        }
        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 *=
                    VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS
                    * (EnableCustomBirth ? m_effect.UserBirthMultiplier : 1.0f)
                    * MyParticlesManager.BirthMultiplierOverall
                    * lodBirth;

                BirthPerFrame.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out m_birthPerFrame);
                m_birthPerFrame *= (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;
                }

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

                    m_birthPerFrame -= 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;
        }
        private void UpdateParticlesLife()
        {
            int counter = 0;

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-UpdateParticlesLife");

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

            m_AABB = BoundingBoxD.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;
                }
            }

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

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ParticleGeneration-Update01");

            Vector3D previousTrail0 = previousParticlePosition;
            Vector3D 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)
                        {
                            var delta = m_effect.GetDeltaMatrix();
                            particle.AddMotionInheritance(ref motionInheritance, ref delta);
                        }

                        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
                            {
                                MyPolyLineD polyLine = new MyPolyLineD();
                                polyLine.Thickness = particle.Thickness;
                                polyLine.Point0    = particle.ActualPosition;
                                polyLine.Point1    = previousParticlePosition;

                                Vector3D direction           = polyLine.Point1 - polyLine.Point0;
                                Vector3D normalizedDirection = MyUtils.Normalize(polyLine.Point1 - polyLine.Point0);

                                polyLine.LineDirectionNormalized = normalizedDirection;
                                var camPos = MyTransparentGeometry.Camera.Translation;
                                MyUtils.GetPolyLineQuad(out particle.Quad, ref polyLine, camPos);

                                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);
                        continue;
                    }

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

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

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
Ejemplo n.º 13
0
        public void RemoveGeneration(MyParticleGeneration generation)
        {
            int index = m_generations.IndexOf(generation);

            RemoveGeneration(index);
        }