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(Vector3D interpolatedEffectPosition) { MyAnimatedParticle particle = MyTransparentGeometry.AddAnimatedParticle(); if (particle == null) { return; } particle.Type = (MyParticleTypeEnum)ParticleType.GetValue <int>(); MyUtils.AssertIsValid(m_effect.WorldMatrix); Vector3D startOffset; m_emitter.CalculateStartPosition(m_effect.GetElapsedTime(), MatrixD.CreateWorld(interpolatedEffectPosition, m_effect.WorldMatrix.Forward, m_effect.WorldMatrix.Up), m_effect.UserEmitterScale * m_effect.UserScale, out startOffset, out particle.StartPosition); Vector3D 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(MyUtils.GetRandomFloat(particle.Life - lifeVar, particle.Life + lifeVar), 0.1f); } Vector3 vel; Velocity.GetInterpolatedValue <Vector3>(m_effect.GetElapsedTime(), out vel); vel.X *= m_effect.UserScale; vel.Y *= m_effect.UserScale; vel.Z *= m_effect.UserScale; particle.Velocity = vel; if (VelocityDir == MyVelocityDirEnum.FromEmitterCenter) { if (!MyUtils.IsZero(startOffset - particle.StartPosition)) { float length = particle.Velocity.Length(); particle.Velocity = MyUtils.Normalize(particle.StartPosition - (Vector3D)startOffset) * length; } } particle.Velocity = Vector3D.TransformNormal(particle.Velocity, GetEffect().WorldMatrix); Angle.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.Angle); float angleVar = AngleVar; if (angleVar > 0) { particle.Angle = MyUtils.GetRandomFloat(particle.Angle - AngleVar, particle.Angle + AngleVar); } RotationSpeed.GetInterpolatedValue <float>(m_effect.GetElapsedTime(), out particle.RotationSpeed); float rotationSpeedVar = RotationSpeedVar; if (rotationSpeedVar > 0) { particle.RotationSpeed = MyUtils.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); } particle.Thickness *= lodRadius; 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); }
public static VRageRender.MyBillboard AddBillboardParticle(MyAnimatedParticle particle, VRageRender.MyBillboard effectBillboard, bool sort) { //MyBillboard billboard = m_preallocatedParticleBillboards.Allocate(); //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard(); VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate(); if (billboard != null) { MyTransparentGeometry.StartParticleProfilingBlock("item.Value.Draw"); if (particle.Draw(billboard) == true) { if (!sort) effectBillboard.ContainedBillboards.Add(billboard); MyPerformanceCounter.PerCameraDrawWrite.NewParticlesCount++; } billboard.CustomViewProjection = -1; MyTransparentGeometry.EndParticleProfilingBlock(); } return billboard; }
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); particle.Flags = GetEffect().IsInFrustum ? particle.Flags | MyAnimatedParticle.ParticleFlags.IsInFrustum : particle.Flags & ~MyAnimatedParticle.ParticleFlags.IsInFrustum; 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 static void DeallocateAnimatedParticle(MyAnimatedParticle particle) { m_animatedParticles.Deallocate(particle); }