Apply boundary sink free-outflow on ghost cells
This commit is contained in:
@@ -65,6 +65,7 @@ namespace FloodSWE.Networking
|
||||
private HashSet<int> activeSourceIds = new HashSet<int>();
|
||||
private HashSet<int> activeSinkIds = new HashSet<int>();
|
||||
private readonly Dictionary<int, int[]> activeBoundaryInflowGhostCells = new Dictionary<int, int[]>();
|
||||
private readonly Dictionary<int, int[]> activeBoundarySinkGhostCells = new Dictionary<int, int[]>();
|
||||
private readonly Dictionary<int, int[]> activeSourceAreaCells = new Dictionary<int, int[]>();
|
||||
private readonly Dictionary<int, int[]> activeSinkCells = new Dictionary<int, int[]>();
|
||||
private bool activeTileHasBoundaryCellGroups;
|
||||
@@ -692,6 +693,7 @@ namespace FloodSWE.Networking
|
||||
activeSourceIds = new HashSet<int>();
|
||||
activeSinkIds = new HashSet<int>();
|
||||
activeBoundaryInflowGhostCells.Clear();
|
||||
activeBoundarySinkGhostCells.Clear();
|
||||
activeSourceAreaCells.Clear();
|
||||
activeSinkCells.Clear();
|
||||
activeTileHasBoundaryCellGroups = false;
|
||||
@@ -714,18 +716,20 @@ namespace FloodSWE.Networking
|
||||
CollectIdsFromRefs(tile.boundary_inflow_ids, activeSourceIds);
|
||||
|
||||
CollectCellGroups(tile.boundary_cells, activeBoundaryInflowGhostCells, activeSourceIds);
|
||||
CollectCellGroups(tile.boundary_sink_cells, activeBoundarySinkGhostCells, activeSinkIds);
|
||||
CollectCellGroups(tile.source_area_cells, activeSourceAreaCells, activeSourceIds);
|
||||
CollectCellGroups(tile.sink_cells, activeSinkCells, activeSinkIds);
|
||||
|
||||
activeTileHasBoundaryCellGroups =
|
||||
activeBoundaryInflowGhostCells.Count > 0 ||
|
||||
activeBoundarySinkGhostCells.Count > 0 ||
|
||||
activeSourceAreaCells.Count > 0 ||
|
||||
activeSinkCells.Count > 0;
|
||||
|
||||
Debug.Log(
|
||||
$"SweServerRuntime: active tile inflowIds={activeSourceIds.Count}, sinkIds={activeSinkIds.Count}, " +
|
||||
$"boundaryGhostGroups={activeBoundaryInflowGhostCells.Count}, sourceAreaGroups={activeSourceAreaCells.Count}, " +
|
||||
$"sinkGroups={activeSinkCells.Count}");
|
||||
$"boundaryInGhostGroups={activeBoundaryInflowGhostCells.Count}, boundaryOutGhostGroups={activeBoundarySinkGhostCells.Count}, " +
|
||||
$"sourceAreaGroups={activeSourceAreaCells.Count}, sinkGroups={activeSinkCells.Count}");
|
||||
}
|
||||
|
||||
private void RecomputeExternalDepthRate()
|
||||
@@ -749,6 +753,8 @@ namespace FloodSWE.Networking
|
||||
var ghostIndices = new List<int>(128);
|
||||
var ghostLevels = new List<float>(128);
|
||||
var ghostVelocities = new List<Vector2>(128);
|
||||
var ghostOutflowCells = new HashSet<int>();
|
||||
var boundarySinkIdsWithGhostOutflow = new HashSet<int>();
|
||||
|
||||
foreach (var pair in activeBoundaryInflowGhostCells)
|
||||
{
|
||||
@@ -786,6 +792,39 @@ namespace FloodSWE.Networking
|
||||
simulator.ClearGhostBoundaryOverrides();
|
||||
}
|
||||
|
||||
foreach (var pair in activeBoundarySinkGhostCells)
|
||||
{
|
||||
int boundaryId = pair.Key;
|
||||
if (boundaryId <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boundarySinkIdsWithGhostOutflow.Add(boundaryId);
|
||||
int[] cells = pair.Value;
|
||||
if (cells == null || cells.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cells.Length; i++)
|
||||
{
|
||||
int idx = cells[i];
|
||||
if (idx >= 0)
|
||||
{
|
||||
ghostOutflowCells.Add(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasGhostOutflow =
|
||||
ghostOutflowCells.Count > 0 &&
|
||||
simulator.SetGhostFreeOutflowCells(new List<int>(ghostOutflowCells).ToArray());
|
||||
if (!hasGhostOutflow)
|
||||
{
|
||||
simulator.ClearGhostFreeOutflowCells();
|
||||
}
|
||||
|
||||
int totalCells = simulator.gridRes * simulator.gridRes;
|
||||
float[] perCell = new float[totalCells];
|
||||
bool hasDepthForcing = false;
|
||||
@@ -834,6 +873,11 @@ namespace FloodSWE.Networking
|
||||
foreach (var pair in activeSinkCells)
|
||||
{
|
||||
int boundaryId = pair.Key;
|
||||
if (boundarySinkIdsWithGhostOutflow.Contains(boundaryId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float rate = 0.0f;
|
||||
if (TryResolveBoundaryProfile("sink", boundaryId, out SweBoundaryProfile profile) && profile != null && profile.enabled)
|
||||
{
|
||||
@@ -897,22 +941,38 @@ namespace FloodSWE.Networking
|
||||
forcedDepthCells = 0;
|
||||
}
|
||||
|
||||
if (!hasGhostForcing && !hasDepthForcing)
|
||||
if (!hasGhostForcing && !hasDepthForcing && !hasGhostOutflow)
|
||||
{
|
||||
lastForcedCellCount = 0;
|
||||
lastForcingStatus = "disabled:no_active_boundary_profiles";
|
||||
return;
|
||||
}
|
||||
|
||||
lastForcedCellCount = ghostIndices.Count + forcedDepthCells;
|
||||
if (hasGhostForcing && hasDepthForcing)
|
||||
lastForcedCellCount = ghostIndices.Count + forcedDepthCells + (hasGhostOutflow ? ghostOutflowCells.Count : 0);
|
||||
if (hasGhostForcing && hasDepthForcing && hasGhostOutflow)
|
||||
{
|
||||
lastForcingStatus = "ghost+localized+free_outflow";
|
||||
}
|
||||
else if (hasGhostForcing && hasDepthForcing)
|
||||
{
|
||||
lastForcingStatus = "ghost+localized";
|
||||
}
|
||||
else if (hasGhostForcing && hasGhostOutflow)
|
||||
{
|
||||
lastForcingStatus = "ghost+free_outflow";
|
||||
}
|
||||
else if (hasDepthForcing && hasGhostOutflow)
|
||||
{
|
||||
lastForcingStatus = "localized+free_outflow";
|
||||
}
|
||||
else if (hasGhostForcing)
|
||||
{
|
||||
lastForcingStatus = "ghost_only";
|
||||
}
|
||||
else if (hasGhostOutflow)
|
||||
{
|
||||
lastForcingStatus = "free_outflow_only";
|
||||
}
|
||||
else
|
||||
{
|
||||
lastForcingStatus = "localized";
|
||||
@@ -921,13 +981,14 @@ namespace FloodSWE.Networking
|
||||
if (verboseDiagnostics)
|
||||
{
|
||||
Debug.Log(
|
||||
$"SweServerRuntime: forcing applied status={lastForcingStatus} ghost={ghostIndices.Count} depth={forcedDepthCells}");
|
||||
$"SweServerRuntime: forcing applied status={lastForcingStatus} ghost={ghostIndices.Count} depth={forcedDepthCells} freeOutflow={ghostOutflowCells.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
private void RecomputeLegacyBoundaryDepthRate()
|
||||
{
|
||||
simulator.ClearGhostBoundaryOverrides();
|
||||
simulator.ClearGhostFreeOutflowCells();
|
||||
|
||||
var sourceRates = new Dictionary<int, float>();
|
||||
foreach (int sourceId in activeSourceIds)
|
||||
|
||||
Reference in New Issue
Block a user