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); }
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); }
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); } } }
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); }
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; } } }
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); }
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(); }
public void RemoveGeneration(MyParticleGeneration generation) { int index = m_generations.IndexOf(generation); RemoveGeneration(index); }