fix(physics): activate collision generations atomically
This commit is contained in:
parent
3e0f3b6206
commit
be94bc9b06
18 changed files with 1402 additions and 80 deletions
|
|
@ -125,4 +125,76 @@ public sealed class CellGraph
|
|||
return stab;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an immutable-reference snapshot for collision-generation
|
||||
/// preparation. EnvCell and TerrainSurface records are immutable after
|
||||
/// publication, so copying the registries is sufficient; the active graph
|
||||
/// remains untouched while the staging graph is rebuilt.
|
||||
/// </summary>
|
||||
internal CellGraph CreateCollisionStagingCopy()
|
||||
{
|
||||
var copy = new CellGraph { CurrCell = CurrCell };
|
||||
foreach ((uint id, EnvCell cell) in _envCells)
|
||||
copy._envCells.TryAdd(id, cell);
|
||||
foreach ((uint id, (TerrainSurface Terrain, Vector3 Origin) terrain) in
|
||||
_terrain)
|
||||
{
|
||||
copy._terrain.TryAdd(id, terrain);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
internal PreparedCellGraphLandblock PrepareLandblockReplacement(
|
||||
uint landblockId)
|
||||
{
|
||||
uint prefix = landblockId & 0xFFFF0000u;
|
||||
KeyValuePair<uint, EnvCell>[] envCells = _envCells
|
||||
.Where(static pair => (pair.Key & 0xFFFFu) >= 0x0100u)
|
||||
.Where(pair => (pair.Key & 0xFFFF0000u) == prefix)
|
||||
.OrderBy(static pair => pair.Key)
|
||||
.ToArray();
|
||||
bool hasTerrain = _terrain.TryGetValue(prefix, out var terrain);
|
||||
return new PreparedCellGraphLandblock(
|
||||
prefix,
|
||||
envCells,
|
||||
hasTerrain,
|
||||
terrain.Terrain,
|
||||
terrain.Origin,
|
||||
CurrCell?.Id ?? 0u);
|
||||
}
|
||||
|
||||
internal void CommitLandblockReplacement(
|
||||
PreparedCellGraphLandblock replacement)
|
||||
{
|
||||
uint currentCellId = CurrCell?.Id ?? 0u;
|
||||
RemoveLandblock(replacement.LandblockPrefix);
|
||||
if (replacement.HasTerrain)
|
||||
{
|
||||
_terrain[replacement.LandblockPrefix] = (
|
||||
replacement.Terrain!,
|
||||
replacement.Origin);
|
||||
}
|
||||
foreach ((uint id, EnvCell cell) in replacement.EnvCells)
|
||||
_envCells[id] = cell;
|
||||
|
||||
uint desiredCurrentCellId =
|
||||
(currentCellId & 0xFFFF0000u) == replacement.LandblockPrefix
|
||||
? currentCellId
|
||||
: currentCellId == 0u
|
||||
&& (replacement.CurrentCellId & 0xFFFF0000u)
|
||||
== replacement.LandblockPrefix
|
||||
? replacement.CurrentCellId
|
||||
: 0u;
|
||||
if (desiredCurrentCellId != 0u)
|
||||
CurrCell = GetVisible(desiredCurrentCellId);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed record PreparedCellGraphLandblock(
|
||||
uint LandblockPrefix,
|
||||
KeyValuePair<uint, EnvCell>[] EnvCells,
|
||||
bool HasTerrain,
|
||||
TerrainSurface? Terrain,
|
||||
Vector3 Origin,
|
||||
uint CurrentCellId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue