Use bytes for internal RGBA components of Color, iterate particles sequentially in ParticleEmitters, increase limit for CPU particles, reduce size of Particle struct.

This commit is contained in:
2024-10-16 00:28:39 +02:00
parent 692fdf8ef0
commit 7c7c61fd56
7 changed files with 71 additions and 78 deletions

View File

@@ -219,7 +219,8 @@ namespace Voile.Rendering
private Raylib_cs.Color VoileColorToRaylibColor(Color color)
{
return new Raylib_cs.Color { r = (byte)Math.Round(color.R * 255f), g = (byte)Math.Round(color.G * 255f), b = (byte)Math.Round(color.B * 255f), a = (byte)Math.Round(color.A * 255f) };
var rayColor = new Raylib_cs.Color(color.R, color.G, color.B, color.A);
return rayColor;
}
public override void DrawText(ResourceRef<Font> fontResource, string text, Color color)

View File

@@ -14,8 +14,6 @@ public struct Particle
public int EmitterIndex { get; set; }
public int ColorArgb { get; set; }
public Vector2 Position { get; set; }
public Vector2 Velocity { get; set; }
public float AngularVelocity { get; set; }
public float LifeTime { get; set; } = 1.0f;
public float Scale { get; set; }
public float Rotation { get; set; }
@@ -61,7 +59,6 @@ public class ParticleEmitterSettingsResourceLoader : ResourceLoader<ParticleEmit
protected override ParticleEmitterSettingsResource LoadResource(string path)
{
// TODO: this is ugly, better to make some sort of wrapper API for TOML files.
var settings = new ParticleEmitterSettings();
using (var reader = new TomlDataReader("ParticleEmitterSettings"))
@@ -116,7 +113,7 @@ public class ParticleEmitter : IUpdatableSystem
_settingsResource = settingsResource;
_maxParticles = _settingsResource.Value.Settings.MaxParticles;
_particleIndex = _maxParticles - 1;
// _particleIndex = _maxParticles - 1;
_positions = positionsSlice;
_velocities = velocitiesSlice;
@@ -131,7 +128,6 @@ public class ParticleEmitter : IUpdatableSystem
return new Particle()
{
Position = _positions[idx],
Velocity = _velocities[idx],
Scale = MathUtils.Lerp(Settings.ScaleEnd, Settings.ScaleBegin, t),
ColorArgb = MathUtils.LerpColor(Settings.ColorEnd, Settings.ColorBegin, t).Argb
};
@@ -149,7 +145,7 @@ public class ParticleEmitter : IUpdatableSystem
}
_maxParticles = Settings.MaxParticles;
_particleIndex = _maxParticles - 1;
_particleIndex = 0;
}
/// <summary>
@@ -166,7 +162,6 @@ public class ParticleEmitter : IUpdatableSystem
}
var deltaTimeVector = new Vector2((float)deltaTime);
var lifeTimeInv = 1.0f / Settings.LifeTime;
var gravityVector = Settings.Gravity * (float)deltaTime;
var dampingFactor = Settings.Damping * (float)deltaTime;
@@ -174,8 +169,6 @@ public class ParticleEmitter : IUpdatableSystem
{
_lifetimes[i] = Math.Max(0.0f, _lifetimes[i] - (float)deltaTime);
var t = _lifetimes[i] * lifeTimeInv;
_velocities[i] += gravityVector;
_positions[i] += _velocities[i] * deltaTimeVector;
@@ -185,8 +178,6 @@ public class ParticleEmitter : IUpdatableSystem
private void Emit()
{
// Particle particle = _particles[_particleIndex];
if (_lifetimes[_particleIndex] > 0) return;
_positions[_particleIndex] = GetEmitPosition();
@@ -194,12 +185,9 @@ public class ParticleEmitter : IUpdatableSystem
_velocities[_particleIndex] += Vector2.One * Settings.LinearVelocityRandom * ((float)_random.NextDouble() - 0.5f);
// particle.AngularVelocity = Settings.AngularVelocity;
// particle.AngularVelocity += 1f * Settings.AngularVelocityRandom * ((float)_random.NextDouble() - 0.5f);
_lifetimes[_particleIndex] = Settings.LifeTime;
_particleIndex = --_particleIndex <= 0 ? _maxParticles - 1 : --_particleIndex;
_particleIndex = (_particleIndex + 1) % _maxParticles;
}
private Vector2 GetEmitPosition()
@@ -233,7 +221,7 @@ public class ParticleSystem : IUpdatableSystem, IDisposable
/// <summary>
/// Maximum amount of particles emittable by the system.
/// </summary>
public int ParticleLimit { get; set; } = 8192;
public int ParticleLimit { get; set; } = short.MaxValue;
/// <summary>
/// List of particle emitters created for this ParticleSystem.
@@ -245,8 +233,6 @@ public class ParticleSystem : IUpdatableSystem, IDisposable
/// </summary>
public ParticleSystem()
{
_particleIndex = ParticleLimit - 1;
_particlePositions = new Vector2[ParticleLimit];
_particleVelocities = new Vector2[ParticleLimit];
_particleLifetimes = new float[ParticleLimit];
@@ -315,20 +301,14 @@ public class ParticleSystem : IUpdatableSystem, IDisposable
}
public void Dispose()
{
CleanupParticles();
}
private void CleanupParticles()
{
Array.Clear(_particlePositions);
Array.Clear(_particleVelocities);
Array.Clear(_particleLifetimes);
}
// private Particle[] _particles;
private Vector2[] _particlePositions, _particleVelocities;
private float[] _particleLifetimes;
private int _particleIndex;
private int _emitterSliceOffset;
private List<ParticleEmitter> _emitters = new();

View File

@@ -34,25 +34,33 @@ namespace Voile
public static Color Green = new(0x00FF00);
public static Color Red = new(0xFF0000);
public float R { get; set; }
public float G { get; set; }
public float B { get; set; }
public float A { get; set; } = 1.0f;
public byte R { get; set; }
public byte G { get; set; }
public byte B { get; set; }
public byte A { get; set; } = 255;
public int Argb
{
get
{
int a = (int)Math.Round(A * 255f) << 24;
int r = (int)Math.Round(R * 255f) << 16;
int g = (int)Math.Round(G * 255f) << 8;
int b = (int)Math.Round(B * 255f);
int a = A << 24;
int r = R << 16;
int g = G << 8;
int b = B;
return a | r | g | b;
}
}
public Color(float r, float g, float b, float a)
public Color(float r, float g, float b, float a = 1.0f)
{
R = (byte)Math.Clamp(r * 255, 0, 255);
G = (byte)Math.Clamp(g * 255, 0, 255);
B = (byte)Math.Clamp(b * 255, 0, 255);
A = (byte)Math.Clamp(a * 255, 0, 255);
}
public Color(byte r, byte g, byte b, byte a = 255)
{
R = r;
G = g;
@@ -60,22 +68,16 @@ namespace Voile
A = a;
}
public Color(byte r, byte g, byte b, byte a)
{
R = r / 255f;
G = g / 255f;
B = b / 255f;
A = a / 255f;
}
public Color(int hex)
{
A = 1.0f;
B = (hex & 0xFF) / 255.0f;
hex >>= 8;
G = (hex & 0xFF) / 255.0f;
hex >>= 8;
R = (hex & 0xFF) / 255.0f;
A = 255; // Default alpha to 255 if not provided
B = (byte)(hex & 0xFF);
G = (byte)((hex >> 8) & 0xFF);
R = (byte)((hex >> 16) & 0xFF);
if (hex > 0xFFFFFF) // If the hex value includes alpha
{
A = (byte)((hex >> 24) & 0xFF);
}
}
public static Color FromHexString(string hex)
@@ -104,20 +106,18 @@ namespace Voile
public Color Lightened(float amount)
{
var result = this;
result.R = result.R + (1.0f - result.R) * amount;
result.G = result.G + (1.0f - result.G) * amount;
result.B = result.B + (1.0f - result.B) * amount;
result.R = (byte)Math.Min(255, R + (255 - R) * amount);
result.G = (byte)Math.Min(255, G + (255 - G) * amount);
result.B = (byte)Math.Min(255, B + (255 - B) * amount);
return result;
}
public Color Darkened(float amount)
{
var result = this;
result.R = result.R * (1.0f - amount);
result.G = result.G * (1.0f - amount);
result.B = result.B * (1.0f - amount);
result.R = (byte)(R * (1.0f - amount));
result.G = (byte)(G * (1.0f - amount));
result.B = (byte)(B * (1.0f - amount));
return result;
}

View File

@@ -17,10 +17,12 @@ namespace Voile
public static Color LerpColor(Color colorA, Color colorB, float t)
{
var r = Lerp(colorA.R, colorB.R, t);
var g = Lerp(colorA.G, colorB.G, t);
var b = Lerp(colorA.B, colorB.B, t);
var a = Lerp(colorA.A, colorB.A, t);
t = Math.Clamp(t, 0f, 1f);
byte r = (byte)(colorA.R + (colorB.R - colorA.R) * t);
byte g = (byte)(colorA.G + (colorB.G - colorA.G) * t);
byte b = (byte)(colorA.B + (colorB.B - colorA.B) * t);
byte a = (byte)(colorA.A + (colorB.A - colorA.A) * t);
return new Color(r, g, b, a);
}