feat(render): implement Campaign AR and terrain fidelity

This commit is contained in:
Erik 2026-08-22 13:13:29 +02:00
parent 99cf26e00c
commit 7a5f96ede5
368 changed files with 50611 additions and 950 deletions

View file

@ -53,6 +53,15 @@ public sealed class TranslucencyFadeManager
// frames keep reading the settled value.
private readonly Dictionary<uint, Dictionary<uint, float>> _committed = new();
private ulong _revision = 1;
/// <summary>
/// Advances whenever the committed per-part opacity topology changes.
/// Render products may use this to retain classification while no fade
/// state changes, and to rebuild exact caster membership when it does.
/// </summary>
public ulong Revision => _revision;
/// <summary>
/// Start (or replace) a translucency ramp for one Setup part of one
/// entity. Mirrors <c>CPhysicsObj::SetPartTranslucency</c>: a
@ -151,8 +160,10 @@ public sealed class TranslucencyFadeManager
/// <summary>Drop all fade state for an entity (despawn / unload).</summary>
public void ClearEntity(uint entityId)
{
_activeFades.Remove(entityId);
_committed.Remove(entityId);
bool changed = _activeFades.Remove(entityId);
changed |= _committed.Remove(entityId);
if (changed)
AdvanceRevision();
}
private void Commit(uint entityId, uint partIndex, float value)
@ -162,6 +173,26 @@ public sealed class TranslucencyFadeManager
parts = new Dictionary<uint, float>();
_committed[entityId] = parts;
}
if (parts.TryGetValue(partIndex, out float prior)
&& BitConverter.SingleToInt32Bits(prior)
== BitConverter.SingleToInt32Bits(value))
{
return;
}
parts[partIndex] = value;
AdvanceRevision();
}
private void AdvanceRevision()
{
if (_revision == ulong.MaxValue)
{
throw new InvalidOperationException(
"Translucency fade revision space was exhausted.");
}
_revision++;
}
}