Refactor to prepare for meta particles

This commit is contained in:
Ammar Askar 2023-08-01 21:26:51 -04:00
parent 7f32393fd2
commit 6163150d6e
3 changed files with 188 additions and 148 deletions

View file

@ -11,27 +11,12 @@ namespace OpenTS2.Content.DBPF.Effects
{ {
public readonly ulong Flags; public readonly ulong Flags;
public readonly Vector2 Life; public readonly ParticleLife Life;
public readonly float LifePreRoll;
public readonly Vector2 RateDelay; public readonly ParticleEmission Emission;
public readonly Vector2 RateTrigger;
public readonly BoundingBox EmitDirection;
public readonly Vector2 EmitSpeed;
public readonly BoundingBox EmitVolume;
public readonly float EmitTorusWidth;
public readonly FloatCurve RateCurve;
public readonly float RateCurveTime;
public readonly ushort RateCurveCycles;
public readonly float RateSpeedScale; public readonly float RateSpeedScale;
public readonly FloatCurve SizeCurve; public readonly ParticleSize Size;
public readonly float SizeVary;
public readonly FloatCurve AspectCurve;
public readonly float AspectVary;
public readonly Vector3 RotateAxis; public readonly Vector3 RotateAxis;
public readonly float RotateOffsetX; public readonly float RotateOffsetX;
@ -39,65 +24,86 @@ namespace OpenTS2.Content.DBPF.Effects
public readonly FloatCurve RotateCurveX; public readonly FloatCurve RotateCurveX;
public readonly FloatCurve RotateCurveY; public readonly FloatCurve RotateCurveY;
public readonly FloatCurve AlphaCurve; public readonly ParticleColor Color;
public readonly float AlphaVary; public readonly ParticleDrawing Drawing;
public readonly Vector3[] Colors;
public readonly Vector3 ColorVary;
public readonly string MaterialName;
public readonly byte TileCountU;
public readonly byte TileCountV;
public readonly byte ParticleAlignmentType;
public readonly byte ParticleDrawType;
public readonly float Layer;
public readonly float FrameSpeed;
public readonly byte FrameStart;
public readonly byte FrameCount;
public readonly float Screw; public readonly float Screw;
public readonly Wiggle[] Wiggles; public readonly Wiggle[] Wiggles;
public readonly byte BloomAlphaRate; public readonly ParticleBloom Bloom;
public readonly byte BloomAlpha;
public readonly byte BloomSizeRate;
public readonly byte BloomSize;
public readonly Collider[] Colliders; public readonly Collider[] Colliders;
public readonly float TerrainBounce; public readonly ParticleTerrainInteraction TerrainInteraction;
public readonly float TerrainRepelHeight;
public readonly float TerrainRepelStrength;
public readonly float TerrainRepelScout;
public readonly float TerrainRepelVertical;
public readonly float TerrainRepelKillHeight;
public readonly float TerrainDeathProbability;
public readonly float DeathByWaterProbability;
public readonly Vector2 RandomWalkDelay; public readonly Vector2 RandomWalkDelay;
public readonly Vector2 RandomWalkStrength; public readonly Vector2 RandomWalkStrength;
public readonly float RandomWalkTurnX; public readonly float RandomWalkTurnX;
public readonly float RandomWalkTurnY; public readonly float RandomWalkTurnY;
public ParticleEffect(ulong flags, Vector2 life, float lifePreRoll, Vector2 rateDelay, Vector2 rateTrigger, public ParticleEffect(ulong flags, ParticleLife life, ParticleEmission emission, float rateSpeedScale,
BoundingBox emitDirection, Vector2 emitSpeed, BoundingBox emitVolume, float emitTorusWidth, ParticleSize size, Vector3 rotateAxis,
FloatCurve rateCurve, float rateCurveTime, ushort rateCurveCycles, float rateSpeedScale,
FloatCurve sizeCurve, float sizeVary, FloatCurve aspectCurve, float aspectVary, Vector3 rotateAxis,
float rotateOffsetX, float rotateOffsetY, FloatCurve rotateCurveX, FloatCurve rotateCurveY, float rotateOffsetX, float rotateOffsetY, FloatCurve rotateCurveX, FloatCurve rotateCurveY,
FloatCurve alphaCurve, float alphaVary, Vector3[] colors, Vector3 colorVary, string materialName, ParticleColor color, ParticleDrawing drawing, float screw, Wiggle[] wiggles, ParticleBloom bloom,
byte tileCountU, byte tileCountV, byte particleAlignmentType, byte particleDrawType, float layer, Collider[] colliders,
float frameSpeed, byte frameStart, byte frameCount, float screw, Wiggle[] wiggles, byte bloomAlphaRate, ParticleTerrainInteraction terrainInteraction, Vector2 randomWalkDelay,
byte bloomAlpha, byte bloomSizeRate, byte bloomSize, Collider[] colliders, float terrainBounce,
float terrainRepelHeight, float terrainRepelStrength, float terrainRepelScout, float terrainRepelVertical, float terrainRepelKillHeight,
float terrainDeathProbability, float deathByWaterProbability, Vector2 randomWalkDelay,
Vector2 randomWalkStrength, float randomWalkTurnX, float randomWalkTurnY) Vector2 randomWalkStrength, float randomWalkTurnX, float randomWalkTurnY)
{ {
Flags = flags; Flags = flags;
Life = life;
Emission = emission;
RateSpeedScale = rateSpeedScale;
Size = size;
RotateAxis = rotateAxis;
RotateOffsetX = rotateOffsetX;
RotateOffsetY = rotateOffsetY;
RotateCurveX = rotateCurveX;
RotateCurveY = rotateCurveY;
Color = color;
Drawing = drawing;
Screw = screw;
Wiggles = wiggles;
Bloom = bloom;
Colliders = colliders;
TerrainInteraction = terrainInteraction;
RandomWalkDelay = randomWalkDelay;
RandomWalkStrength = randomWalkStrength;
RandomWalkTurnX = randomWalkTurnX;
RandomWalkTurnY = randomWalkTurnY;
}
}
public struct ParticleLife
{
public Vector2 Life { get; }
public float LifePreRoll { get; }
public ParticleLife(Vector2 life, float lifePreRoll)
{
Life = life; Life = life;
LifePreRoll = lifePreRoll; LifePreRoll = lifePreRoll;
}
}
public struct ParticleEmission
{
public Vector2 RateDelay { get; }
public Vector2 RateTrigger { get; }
public BoundingBox EmitDirection { get; }
public Vector2 EmitSpeed { get; }
public BoundingBox EmitVolume { get; }
public float EmitTorusWidth { get; }
public FloatCurve RateCurve { get; }
public float RateCurveTime { get; }
public ushort RateCurveCycles { get; }
public ParticleEmission(Vector2 rateDelay, Vector2 rateTrigger, BoundingBox emitDirection, Vector2 emitSpeed,
BoundingBox emitVolume, float emitTorusWidth, FloatCurve rateCurve, float rateCurveTime,
ushort rateCurveCycles)
{
RateDelay = rateDelay; RateDelay = rateDelay;
RateTrigger = rateTrigger; RateTrigger = rateTrigger;
EmitDirection = emitDirection; EmitDirection = emitDirection;
@ -107,20 +113,60 @@ namespace OpenTS2.Content.DBPF.Effects
RateCurve = rateCurve; RateCurve = rateCurve;
RateCurveTime = rateCurveTime; RateCurveTime = rateCurveTime;
RateCurveCycles = rateCurveCycles; RateCurveCycles = rateCurveCycles;
RateSpeedScale = rateSpeedScale; }
}
public struct ParticleSize
{
public FloatCurve SizeCurve { get; }
public float SizeVary { get; }
public FloatCurve AspectCurve { get; }
public float AspectVary { get; }
public ParticleSize(FloatCurve sizeCurve, float sizeVary, FloatCurve aspectCurve, float aspectVary)
{
SizeCurve = sizeCurve; SizeCurve = sizeCurve;
SizeVary = sizeVary; SizeVary = sizeVary;
AspectCurve = aspectCurve; AspectCurve = aspectCurve;
AspectVary = aspectVary; AspectVary = aspectVary;
RotateAxis = rotateAxis; }
RotateOffsetX = rotateOffsetX; }
RotateOffsetY = rotateOffsetY;
RotateCurveX = rotateCurveX; public struct ParticleColor
RotateCurveY = rotateCurveY; {
public FloatCurve AlphaCurve { get; }
public float AlphaVary { get; }
public Vector3[] Colors { get; }
public Vector3 ColorVary { get; }
public ParticleColor(FloatCurve alphaCurve, float alphaVary, Vector3[] colors, Vector3 colorVary)
{
AlphaCurve = alphaCurve; AlphaCurve = alphaCurve;
AlphaVary = alphaVary; AlphaVary = alphaVary;
Colors = colors; Colors = colors;
ColorVary = colorVary; ColorVary = colorVary;
}
}
public struct ParticleDrawing
{
public string MaterialName { get; }
public byte TileCountU { get; }
public byte TileCountV { get; }
public byte ParticleAlignmentType { get; }
public byte ParticleDrawType { get; }
public float Layer { get; }
public float FrameSpeed { get; }
public byte FrameStart { get; }
public byte FrameCount { get; }
public ParticleDrawing(string materialName, byte tileCountU, byte tileCountV, byte particleAlignmentType,
byte particleDrawType, float layer, float frameSpeed, byte frameStart, byte frameCount)
{
MaterialName = materialName; MaterialName = materialName;
TileCountU = tileCountU; TileCountU = tileCountU;
TileCountV = tileCountV; TileCountV = tileCountV;
@ -130,25 +176,47 @@ namespace OpenTS2.Content.DBPF.Effects
FrameSpeed = frameSpeed; FrameSpeed = frameSpeed;
FrameStart = frameStart; FrameStart = frameStart;
FrameCount = frameCount; FrameCount = frameCount;
Screw = screw; }
Wiggles = wiggles; }
BloomAlphaRate = bloomAlphaRate;
BloomAlpha = bloomAlpha; public struct ParticleTerrainInteraction
BloomSizeRate = bloomSizeRate; {
BloomSize = bloomSize; public float Bounce { get; }
Colliders = colliders; public float RepelHeight { get; }
TerrainBounce = terrainBounce; public float RepelStrength { get; }
TerrainRepelHeight = terrainRepelHeight; public float RepelScout { get; }
TerrainRepelStrength = terrainRepelStrength; public float RepelVertical { get; }
TerrainRepelScout = terrainRepelScout; public float KillHeight { get; }
TerrainRepelVertical = terrainRepelVertical; public float TerrainDeathProbability { get; }
TerrainRepelKillHeight = terrainRepelKillHeight; public float WaterDeathProbability { get; }
public ParticleTerrainInteraction(float bounce, float repelHeight, float repelStrength, float repelScout,
float repelVertical, float killHeight, float terrainDeathProbability, float waterDeathProbability)
{
Bounce = bounce;
RepelHeight = repelHeight;
RepelStrength = repelStrength;
RepelScout = repelScout;
RepelVertical = repelVertical;
KillHeight = killHeight;
TerrainDeathProbability = terrainDeathProbability; TerrainDeathProbability = terrainDeathProbability;
DeathByWaterProbability = deathByWaterProbability; WaterDeathProbability = waterDeathProbability;
RandomWalkDelay = randomWalkDelay; }
RandomWalkStrength = randomWalkStrength; }
RandomWalkTurnX = randomWalkTurnX;
RandomWalkTurnY = randomWalkTurnY; public struct ParticleBloom
{
public byte AlphaRate { get; }
public byte Alpha { get; }
public byte SizeRate { get; }
public byte Size { get; }
public ParticleBloom(byte alphaRate, byte alpha, byte sizeRate, byte size)
{
AlphaRate = alphaRate;
Alpha = alpha;
SizeRate = sizeRate;
Size = size;
} }
} }
} }

View file

@ -52,8 +52,7 @@ namespace OpenTS2.Files.Formats.DBPF
var flags = version < 5 ? reader.ReadUInt32() : reader.ReadUInt64(); var flags = version < 5 ? reader.ReadUInt32() : reader.ReadUInt64();
// Particle life. // Particle life.
var life = Vector2Serializer.Deserialize(reader); var life = new ParticleLife(life: Vector2Serializer.Deserialize(reader), lifePreRoll: reader.ReadFloat());
var lifePreRoll = reader.ReadFloat();
// Rate and emission. // Rate and emission.
var rateDelay = Vector2Serializer.Deserialize(reader); var rateDelay = Vector2Serializer.Deserialize(reader);
@ -71,15 +70,14 @@ namespace OpenTS2.Files.Formats.DBPF
var rateCurve = FloatCurve.Deserialize(reader); var rateCurve = FloatCurve.Deserialize(reader);
var rateCurveTime = reader.ReadFloat(); var rateCurveTime = reader.ReadFloat();
var rateCurveCycles = reader.ReadUInt16(); var rateCurveCycles = reader.ReadUInt16();
var emission = new ParticleEmission(rateDelay, rateTrigger, emitDirectionBBox, emitSpeed, emitVolumeBBox,
emitTorusWidth, rateCurve, rateCurveTime, rateCurveCycles);
var rateSpeedScale = reader.ReadFloat(); var rateSpeedScale = reader.ReadFloat();
// Size. var size = new ParticleSize(
var sizeCurve = FloatCurve.Deserialize(reader); sizeCurve: FloatCurve.Deserialize(reader), sizeVary: reader.ReadFloat(),
var sizeVary = reader.ReadFloat(); aspectCurve: FloatCurve.Deserialize(reader), aspectVary: reader.ReadFloat());
// Aspect ratio?
var aspectCurve = FloatCurve.Deserialize(reader);
var aspectVary = reader.ReadFloat();
// Rotation stuff, a bunch of unknowns here. // Rotation stuff, a bunch of unknowns here.
var rotateAxis = Vector3Serializer.Deserialize(reader); var rotateAxis = Vector3Serializer.Deserialize(reader);
@ -108,26 +106,21 @@ namespace OpenTS2.Files.Formats.DBPF
Vector3Serializer.Deserialize(reader); Vector3Serializer.Deserialize(reader);
} }
// Alpha. // Color.
var alphaCurve = FloatCurve.Deserialize(reader); var alphaCurve = FloatCurve.Deserialize(reader);
var alphaVary = reader.ReadFloat(); var alphaVary = reader.ReadFloat();
// Color.
var colors = ReadMultipleVectors(reader); var colors = ReadMultipleVectors(reader);
var colorVary = Vector3Serializer.Deserialize(reader); var colorVary = Vector3Serializer.Deserialize(reader);
var color = new ParticleColor(alphaCurve, alphaVary, colors, colorVary);
// Texture. // Texture.
var materialName = reader.ReadUint32PrefixedString(); var drawing = new ParticleDrawing(
var tileCountU = reader.ReadByte(); materialName: reader.ReadUint32PrefixedString(),
var tileCountV = reader.ReadByte(); tileCountU: reader.ReadByte(), tileCountV: reader.ReadByte(),
particleAlignmentType: reader.ReadByte(), particleDrawType: reader.ReadByte(),
var particleAlignmentType = reader.ReadByte(); layer: reader.ReadFloat(), frameSpeed: reader.ReadFloat(), frameStart: reader.ReadByte(),
var particleDrawType = reader.ReadByte(); frameCount: reader.ReadByte()
);
var layer = reader.ReadFloat();
var frameSpeed = reader.ReadFloat();
var frameStart = reader.ReadByte();
var frameCount = reader.ReadByte();
Vector3Serializer.Deserialize(reader); Vector3Serializer.Deserialize(reader);
reader.ReadFloat(); reader.ReadFloat();
@ -141,23 +134,22 @@ namespace OpenTS2.Files.Formats.DBPF
var wiggles = Wiggle.DeserializeList(reader); var wiggles = Wiggle.DeserializeList(reader);
// Bloom. // Bloom.
var bloomAlphaRate = reader.ReadByte(); var bloom = new ParticleBloom(alphaRate: reader.ReadByte(), alpha: reader.ReadByte(),
var bloomAlpha = reader.ReadByte(); sizeRate: reader.ReadByte(), size: reader.ReadByte());
var bloomSizeRate = reader.ReadByte();
var bloomSize = reader.ReadByte();
var colliders = Collider.DeserializeList(reader); var colliders = Collider.DeserializeList(reader);
reader.ReadUint32PrefixedString(); reader.ReadUint32PrefixedString();
// Terrain interaction. // Terrain interaction.
var terrainBounce = reader.ReadFloat(); var terrainInteraction = new ParticleTerrainInteraction(
var terrainRepelHeight = reader.ReadFloat(); bounce: reader.ReadFloat(),
var terrainRepelStrength = reader.ReadFloat(); repelHeight: reader.ReadFloat(),
var terrainRepelScout = reader.ReadFloat(); repelStrength: reader.ReadFloat(),
var terrainRepelVertical = reader.ReadFloat(); repelScout: reader.ReadFloat(),
var terrainRepelKillHeight = reader.ReadFloat(); repelVertical: reader.ReadFloat(),
var terrainDeathProbability = reader.ReadFloat(); killHeight: reader.ReadFloat(),
var deathByWaterProbability = reader.ReadFloat(); terrainDeathProbability: reader.ReadFloat(), waterDeathProbability: reader.ReadFloat()
);
Vector2Serializer.Deserialize(reader); Vector2Serializer.Deserialize(reader);
@ -179,30 +171,10 @@ namespace OpenTS2.Files.Formats.DBPF
throw new NotImplementedException("Particle versions 5 and above not implemented yet"); throw new NotImplementedException("Particle versions 5 and above not implemented yet");
} }
return new ParticleEffect(flags: flags, life: life, lifePreRoll: lifePreRoll, rateDelay: rateDelay, return new ParticleEffect(flags, life, emission, rateSpeedScale: rateSpeedScale,
rateTrigger: rateTrigger, emitDirection: emitDirectionBBox, emitSpeed: emitSpeed, size, rotateAxis, rotateOffsetX, rotateOffsetY: rotateOffsetY, rotateCurveX: rotateCurveX, rotateCurveY,
emitVolume: emitVolumeBBox, emitTorusWidth: emitTorusWidth, rateCurve: rateCurve, color, drawing, screw, wiggles, bloom,
rateCurveTime: rateCurveTime, rateCurveCycles: rateCurveCycles, rateSpeedScale: rateSpeedScale, colliders, terrainInteraction, randomWalkDelay, randomWalkStrength, randomWalkTurnX, randomWalkTurnY);
sizeCurve: sizeCurve, sizeVary: sizeVary, aspectCurve: aspectCurve, aspectVary: aspectVary,
rotateAxis: rotateAxis,
rotateOffsetX: rotateOffsetX, rotateOffsetY: rotateOffsetY, rotateCurveX: rotateCurveX,
rotateCurveY: rotateCurveY,
alphaCurve: alphaCurve, alphaVary: alphaVary, colors: colors, colorVary: colorVary,
materialName: materialName,
tileCountU: tileCountU, tileCountV: tileCountV, particleAlignmentType: particleAlignmentType,
particleDrawType: particleDrawType,
layer: layer, frameSpeed: frameSpeed, frameStart: frameStart, frameCount: frameCount, screw: screw,
wiggles: wiggles,
bloomAlphaRate: bloomAlphaRate, bloomAlpha: bloomAlpha, bloomSizeRate: bloomSizeRate,
bloomSize: bloomSize,
colliders: colliders, terrainBounce: terrainBounce, terrainRepelHeight: terrainRepelHeight,
terrainRepelStrength: terrainRepelStrength,
terrainRepelScout: terrainRepelScout,
terrainRepelVertical: terrainRepelVertical, terrainRepelKillHeight: terrainRepelKillHeight,
terrainDeathProbability: terrainDeathProbability,
deathByWaterProbability: deathByWaterProbability, randomWalkDelay: randomWalkDelay,
randomWalkStrength: randomWalkStrength,
randomWalkTurnX: randomWalkTurnX, randomWalkTurnY: randomWalkTurnY);
} }
} }
} }

View file

@ -32,20 +32,20 @@ public class EffectsCodecTest
.GetAsset<EffectsAsset>(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); .GetAsset<EffectsAsset>(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS));
var particle = effectsAsset.Particles[0]; var particle = effectsAsset.Particles[0];
Assert.That(particle.Life, Is.EqualTo(new Vector2(1, 1))); Assert.That(particle.Life.Life, Is.EqualTo(new Vector2(1, 1)));
Assert.That(particle.MaterialName, Is.EqualTo("effects-puff")); Assert.That(particle.Drawing.MaterialName, Is.EqualTo("effects-puff"));
Assert.That(particle.TileCountU, Is.EqualTo(1)); Assert.That(particle.Drawing.TileCountU, Is.EqualTo(1));
Assert.That(particle.TileCountV, Is.EqualTo(1)); Assert.That(particle.Drawing.TileCountV, Is.EqualTo(1));
Assert.That(particle.Wiggles.Length, Is.EqualTo(0)); Assert.That(particle.Wiggles.Length, Is.EqualTo(0));
Assert.That(particle.Colliders.Length, Is.EqualTo(0)); Assert.That(particle.Colliders.Length, Is.EqualTo(0));
Assert.That(particle.TerrainBounce, Is.EqualTo(1.0f)); Assert.That(particle.TerrainInteraction.Bounce, Is.EqualTo(1.0f));
Assert.That(particle.TerrainRepelKillHeight, Is.EqualTo(-1000000000.0f)); Assert.That(particle.TerrainInteraction.KillHeight, Is.EqualTo(-1000000000.0f));
Assert.That(particle.TerrainDeathProbability, Is.EqualTo(0.0f)); Assert.That(particle.TerrainInteraction.TerrainDeathProbability, Is.EqualTo(0.0f));
Assert.That(particle.DeathByWaterProbability, Is.EqualTo(1.0f)); Assert.That(particle.TerrainInteraction.WaterDeathProbability, Is.EqualTo(1.0f));
Assert.That(particle.RandomWalkStrength, Is.EqualTo(new Vector2(50, 50))); Assert.That(particle.RandomWalkStrength, Is.EqualTo(new Vector2(50, 50)));
Assert.That(particle.RandomWalkTurnX, Is.EqualTo(0.1).Within(0.005)); Assert.That(particle.RandomWalkTurnX, Is.EqualTo(0.1).Within(0.005));