Files
MonoGame.Extended/tests/MonoGame.Extended.Tests/Particles/ParticleEffectReaderTests.cs
T
Christopher Whitley 2ea7e85398 Updates to particle system for ember editor (#1001)
* Add enabled state for modifiers

* Add enabled state for interpolators

* Move AutoTrigger to effect not emitters

* Remove LineUniformProfile

* Set Enabled field true by default

* Don't render invisible emitters

* Remove unused member

* Document update method

* Add documentation

* Remove test now that LineUniformProfile was removed

* Fix unit tests
2025-07-25 00:52:05 -04:00

1141 lines
52 KiB
C#

// Copyright (c) Craftwork Games. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
using System;
using System.IO;
using System.Xml;
using Microsoft.Xna.Framework;
using MonoGame.Extended.Particles;
using MonoGame.Extended.Particles.Modifiers;
using MonoGame.Extended.Particles.Modifiers.Containers;
using MonoGame.Extended.Particles.Modifiers.Interpolators;
using MonoGame.Extended.Particles.Profiles;
namespace MonoGame.Extended.Tests.Particles;
public class ParticleEffectReaderTests
{
private readonly MockContentManager _mockContentManager;
public ParticleEffectReaderTests()
{
_mockContentManager = new MockContentManager();
}
private ParticleEffect ReadParticleEffectFromXml(string xml)
{
using MemoryStream stream = new MemoryStream();
using StreamWriter writer = new StreamWriter(stream);
writer.Write(xml);
writer.Flush();
stream.Position = 0;
using ParticleEffectReader reader = new ParticleEffectReader(stream, _mockContentManager);
return reader.ReadParticleEffect();
}
[Fact]
public void ReadParticleEffect_NulLStream_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => new ParticleEffectReader((Stream)null, _mockContentManager));
}
[Fact]
public void ReadParticleEffect_NullContentManager_ThrowsArgumentNullException()
{
using MemoryStream stream = new MemoryStream();
Assert.Throws<ArgumentNullException>(() => new ParticleEffectReader(stream, null));
}
[Fact]
public void ReadParticleEffect_InvalidXmlRoot_ThrowsXmlException()
{
string xml = "<InvalidRoot />";
Assert.Throws<XmlException>(() => ReadParticleEffectFromXml(xml));
}
[Fact]
public void ReadParticleEffect_EmptyEffect_ReturnsExpected()
{
string xml =
"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="EmptyEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1" />
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Equal("EmptyEffect", effect.Name);
Assert.Equal(Vector2.Zero, effect.Position);
Assert.Equal(0.0f, effect.Rotation);
Assert.Equal(Vector2.One, effect.Scale);
Assert.Empty(effect.Emitters);
Assert.True(effect.AutoTrigger);
Assert.Equal(effect.AutoTriggerFrequency, 1.0f);
}
[Fact]
public void ReadParticleEffect_EmptyModifiers_ReturnsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="EmptyModifiers" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Empty(emitter.Modifiers);
}
[Fact]
public void ReadParticleEffect_EmptyInterpolators_ReturnsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Empty(modifier.Interpolators);
}
[Fact]
public void ReadParticleEffect_BoxFillProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="BoxFillProfile" Width="1" Height="1" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
BoxFillProfile profile = Assert.IsType<BoxFillProfile>(emitter.Profile);
Assert.Equal(1.0f, profile.Height);
Assert.Equal(1.0f, profile.Height);
}
[Fact]
public void ReadParticleEffect_BoxProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="BoxProfile" Width="1" Height="1" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
BoxProfile profile = Assert.IsType<BoxProfile>(emitter.Profile);
Assert.Equal(1.0f, profile.Height);
Assert.Equal(1.0f, profile.Height);
}
[Fact]
public void ReadParticleEffect_BoxUniformProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="BoxUniformProfile" Width="1" Height="1" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
BoxUniformProfile profile = Assert.IsType<BoxUniformProfile>(emitter.Profile);
Assert.Equal(1.0f, profile.Height);
Assert.Equal(1.0f, profile.Height);
}
[Fact]
public void ReadParticleEffect_CircleProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="CircleProfile" Radius="1" Radiate="Out" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
CircleProfile profile = Assert.IsType<CircleProfile>(emitter.Profile);
Assert.Equal(1.0f, profile.Radius);
Assert.Equal(CircleRadiation.Out, profile.Radiate);
}
[Fact]
public void ReadParticleEffect_LineProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="LineProfile" Axis="1,1" Length="1" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
LineProfile profile = Assert.IsType<LineProfile>(emitter.Profile);
Assert.Equal(Vector2.One, profile.Axis);
Assert.Equal(1.0f, profile.Length);
}
[Fact]
public void ReadParticleEffect_PointProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
PointProfile profile = Assert.IsType<PointProfile>(emitter.Profile);
}
[Fact]
public void ReadParticleEffect_RingProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="RingProfile" Radius="1" Radiate="In" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
RingProfile profile = Assert.IsType<RingProfile>(emitter.Profile);
Assert.Equal(1.0f, profile.Radius);
Assert.Equal(CircleRadiation.In, profile.Radiate);
}
[Fact]
public void ReadParticleEffect_SprayProfile_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="SprayProfile" Direction="1,1" Spread="1" />
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
SprayProfile profile = Assert.IsType<SprayProfile>(emitter.Profile);
Assert.Equal(Vector2.One, profile.Direction);
Assert.Equal(1.0f, profile.Spread);
}
[Fact]
public void ReadParticleEffect_AgeModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("AgeModifier", modifier.Name);
}
[Fact]
public void ReadParticleEffect_CircleContainerModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="CircleContainerModifier" Frequency="60" Type="CircleContainerModifier" Radius="0" Inside="True" RestitutionCoefficient="1" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
CircleContainerModifier modifier = Assert.IsType<CircleContainerModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("CircleContainerModifier", modifier.Name);
Assert.Equal(0.0f, modifier.Radius);
Assert.True(modifier.Inside);
Assert.Equal(1.0f, modifier.RestitutionCoefficient);
}
[Fact]
public void ReadParticleEffect_DragModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="DragModifier" Frequency="60" Type="DragModifier" DragCoefficient="0.47" Density="0.5" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
DragModifier modifier = Assert.IsType<DragModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("DragModifier", modifier.Name);
Assert.Equal(0.47f, modifier.DragCoefficient);
Assert.Equal(0.5f, modifier.Density);
}
[Fact]
public void ReadParticleEffect_LinearGravityModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="LinearGravityModifier" Frequency="60" Type="LinearGravityModifier" Direction="0,0" Strength="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
LinearGravityModifier modifier = Assert.IsType<LinearGravityModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("LinearGravityModifier", modifier.Name);
Assert.Equal(Vector2.Zero, modifier.Direction);
Assert.Equal(0.0f, modifier.Strength);
}
[Fact]
public void ReadParticleEffect_OpacityFastFadeModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="OpacityFastFadeModifier" Frequency="60" Type="OpacityFastFadeModifier" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
OpacityFastFadeModifier modifier = Assert.IsType<OpacityFastFadeModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("OpacityFastFadeModifier", modifier.Name);
}
[Fact]
public void ReadParticleEffect_RectangleContainerModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="RectangleContainerModifier" Frequency="60" Type="RectangleContainerModifier" Width="0" Height="0" RestitutionCoefficient="1" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
RectangleContainerModifier modifier = Assert.IsType<RectangleContainerModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("RectangleContainerModifier", modifier.Name);
Assert.Equal(0.0f, modifier.Width);
Assert.Equal(0.0f, modifier.Height);
Assert.Equal(1.0f, modifier.RestitutionCoefficient);
}
[Fact]
public void ReadParticleEffect_RectangleLoopContainerModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="RectangleLoopContainerModifier" Frequency="60" Type="RectangleLoopContainerModifier" Width="0" Height="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
RectangleLoopContainerModifier modifier = Assert.IsType<RectangleLoopContainerModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("RectangleLoopContainerModifier", modifier.Name);
Assert.Equal(0.0f, modifier.Width);
Assert.Equal(0.0f, modifier.Height);
}
[Fact]
public void ReadParticleEffect_RotationModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="RotationModifier" Frequency="60" Type="RotationModifier" RotationRate="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
RotationModifier modifier = Assert.IsType<RotationModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("RotationModifier", modifier.Name);
Assert.Equal(0.0f, modifier.RotationRate);
}
[Fact]
public void ReadParticleEffect_VelocityColorModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="VelocityColorModifier" Frequency="60" Type="VelocityColorModifier" StationaryColor="0,0,0" VelocityColor="0,0,0" VelocityThreshold="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
VelocityColorModifier modifier = Assert.IsType<VelocityColorModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("VelocityColorModifier", modifier.Name);
Assert.Equal(Vector3.Zero, modifier.StationaryColor);
Assert.Equal(Vector3.Zero, modifier.VelocityColor);
Assert.Equal(0.0f, modifier.VelocityThreshold);
}
[Fact]
public void ReadParticleEffect_VelocityModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="VelocityModifier" Frequency="60" Type="VelocityModifier" VelocityThreshold="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
VelocityModifier modifier = Assert.IsType<VelocityModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("VelocityModifier", modifier.Name);
Assert.Equal(0.0f, modifier.VelocityThreshold);
}
[Fact]
public void ReadParticleEffect_VortexModifier_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="VortexModifier" Frequency="60" Type="VortexModifier" Position="0,0" Mass="0" MaxSpeed="0" />
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
VortexModifier modifier = Assert.IsType<VortexModifier>(effect.Emitters[0].Modifiers[0]);
Assert.Equal(60.0f, modifier.Frequency);
Assert.Equal("VortexModifier", modifier.Name);
Assert.Equal(Vector2.Zero, modifier.Position);
Assert.Equal(0.0f, modifier.Mass);
Assert.Equal(0.0f, modifier.MaxSpeed);
}
[Fact]
public void ReadParticleEffect_ColorInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="ColorInterpolator" Type="ColorInterpolator" StartValue="0,0,0" EndValue="0,0,0" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
ColorInterpolator interpolator = Assert.IsType<ColorInterpolator>(modifier.Interpolators[0]);
Assert.Equal(Vector3.Zero, interpolator.StartValue);
Assert.Equal(Vector3.Zero, interpolator.EndValue);
}
[Fact]
public void ReadParticleEffect_HueInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="HueInterpolator" Type="HueInterpolator" StartValue="0" EndValue="0" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
HueInterpolator interpolator = Assert.IsType<HueInterpolator>(modifier.Interpolators[0]);
Assert.Equal(0.0f, interpolator.StartValue);
Assert.Equal(0.0f, interpolator.EndValue);
}
[Fact]
public void ReadParticleEffect_OpacityInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="OpacityInterpolator" Type="OpacityInterpolator" StartValue="0" EndValue="0" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
OpacityInterpolator interpolator = Assert.IsType<OpacityInterpolator>(modifier.Interpolators[0]);
Assert.Equal(0.0f, interpolator.StartValue);
Assert.Equal(0.0f, interpolator.EndValue);
}
[Fact]
public void ReadParticleEffect_RotationInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="RotationInterpolator" Type="RotationInterpolator" StartValue="0" EndValue="0" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
RotationInterpolator interpolator = Assert.IsType<RotationInterpolator>(modifier.Interpolators[0]);
Assert.Equal(0.0f, interpolator.StartValue);
Assert.Equal(0.0f, interpolator.EndValue);
}
[Fact]
public void ReadParticleEffect_ScaleInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0,0" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="ScaleInterpolator" Type="ScaleInterpolator" StartValue="0,0" EndValue="1,1" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
ScaleInterpolator interpolator = Assert.IsType<ScaleInterpolator>(modifier.Interpolators[0]);
Assert.Equal(Vector2.Zero, interpolator.StartValue);
Assert.Equal(Vector2.One, interpolator.EndValue);
}
[Fact]
public void ReadParticleEffect_VelocityInterpolator_ReadsExpected()
{
string xml =
$"""
<?xml version="1.0" encoding="utf-8"?>
<ParticleEffect Name="TestEffect" Position="0,0" Rotation="0" Scale="1,1" AutoTrigger="True" AutoTriggerFrequency="1">
<Emitters>
<ParticleEmitter Name="TestEmitter" LifeSpan="1" Offset="0,0" LayerDepth="0" ReclaimFrequency="60" Capacity="1" ModifierExecutionStrategy="Serial" RenderingOrder="FrontToBack">
<Parameters>
<Quantity Kind="Random" RandomMin="5" RandomMax="100" />
<Speed Kind="Random" RandomMin="50" RandomMax="100" />
<Color Kind="Constant" Constant="1,1,1" />
<Opacity Kind="Random" RandomMin="0" RandomMax="1" />
<Scale Kind="Random" RandomMin="0.5,0.5" RandomMax="1,1" />
<Rotation Kind="Random" RandomMin="{-MathF.PI}" RandomMax="{MathF.PI}" />
<Mass Kind="Constant" Constant="1" />
</Parameters>
<Profile Type="PointProfile" />
<Modifiers>
<Modifier Name="AgeModifier" Frequency="60" Type="AgeModifier">
<Interpolators>
<Interpolator Name="VelocityInterpolator" Type="VelocityInterpolator" StartValue="0,0" EndValue="0,0" />
</Interpolators>
</Modifier>
</Modifiers>
</ParticleEmitter>
</Emitters>
</ParticleEffect>
""";
ParticleEffect effect = ReadParticleEffectFromXml(xml);
Assert.Single(effect.Emitters);
ParticleEmitter emitter = effect.Emitters[0];
Assert.Single(emitter.Modifiers);
AgeModifier modifier = Assert.IsType<AgeModifier>(emitter.Modifiers[0]);
Assert.Single(modifier.Interpolators);
VelocityInterpolator interpolator = Assert.IsType<VelocityInterpolator>(modifier.Interpolators[0]);
Assert.Equal(Vector2.Zero, interpolator.StartValue);
Assert.Equal(Vector2.Zero, interpolator.EndValue);
}
}