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