feat(vfx): bind effects to live animated poses

This commit is contained in:
Erik 2026-07-14 10:56:01 +02:00
parent 96ddfdf175
commit 542dcfc384
41 changed files with 3246 additions and 741 deletions

View file

@ -14,8 +14,6 @@ namespace AcDream.Core.Vfx;
/// </summary>
public sealed class EmitterDescRegistry
{
private const uint FallbackEmitterId = 0xFFFFFFFFu;
private readonly Func<uint, DatParticleEmitter?>? _resolver;
private readonly ConcurrentDictionary<uint, EmitterDesc> _byId = new();
@ -32,7 +30,6 @@ public sealed class EmitterDescRegistry
public EmitterDescRegistry(Func<uint, DatParticleEmitter?>? resolver)
{
_resolver = resolver;
Register(BuildFallback());
}
public void Register(EmitterDesc desc)
@ -43,9 +40,16 @@ public sealed class EmitterDescRegistry
public EmitterDesc Get(uint emitterId)
{
if (_byId.TryGetValue(emitterId, out var desc))
if (TryGet(emitterId, out EmitterDesc? desc))
return desc;
throw new KeyNotFoundException(
$"ParticleEmitterInfo 0x{emitterId:X8} was not found.");
}
public bool TryGet(uint emitterId, out EmitterDesc desc)
{
if (_byId.TryGetValue(emitterId, out desc!))
return true;
if (_resolver is not null)
{
var dat = _resolver(emitterId);
@ -53,14 +57,11 @@ public sealed class EmitterDescRegistry
{
desc = FromDat(emitterId, dat);
_byId[emitterId] = desc;
return desc;
return true;
}
}
if (_byId.TryGetValue(FallbackEmitterId, out var fallback))
return fallback;
throw new InvalidOperationException("No default emitter registered in registry.");
desc = null!;
return false;
}
public int Count => _byId.Count;
@ -145,36 +146,6 @@ public sealed class EmitterDescRegistry
}
}
private static EmitterDesc BuildFallback() => new()
{
DatId = FallbackEmitterId,
Type = ParticleType.LocalVelocity,
EmitterKind = ParticleEmitterKind.BirthratePerSec,
Flags = EmitterFlags.Billboard | EmitterFlags.FaceCamera,
Birthrate = 0.1f,
EmitRate = 10f,
MaxParticles = 32,
LifetimeMin = 0.6f,
LifetimeMax = 1.2f,
Lifespan = 0.9f,
LifespanRand = 0.3f,
OffsetDir = new Vector3(0, 0, 1),
MinOffset = 0f,
MaxOffset = 0.1f,
SpawnDiskRadius = 0.1f,
InitialVelocity = new Vector3(0, 0, 0.5f),
VelocityJitter = 0.3f,
A = new Vector3(0, 0, 0.5f),
MinA = 1f,
MaxA = 1f,
B = Vector3.Zero,
C = Vector3.Zero,
StartSize = 0.25f,
EndSize = 0.6f,
StartAlpha = 0.85f,
EndAlpha = 0f,
};
private static ParticleEmitterKind MapEmitterKind(DatEmitterType type) => type switch
{
DatEmitterType.BirthratePerSec => ParticleEmitterKind.BirthratePerSec,