Rewrite and document the visible cells calculation.
This commit is contained in:
@@ -229,30 +229,40 @@ namespace OpenRA.Graphics
|
|||||||
CellRegion CalculateVisibleCells(bool insideBounds)
|
CellRegion CalculateVisibleCells(bool insideBounds)
|
||||||
{
|
{
|
||||||
var map = worldRenderer.World.Map;
|
var map = worldRenderer.World.Map;
|
||||||
var wtl = worldRenderer.Position(TopLeft);
|
|
||||||
var wbr = worldRenderer.Position(BottomRight);
|
|
||||||
|
|
||||||
// Map editor shows the full map (including the area outside the regular bounds)
|
// Calculate the viewport corners in "projected wpos" (at ground level), and
|
||||||
Func<MPos, MPos> clamp = map.Clamp;
|
// this to an equivalent projected cell for the two corners
|
||||||
if (!insideBounds)
|
var tl = map.CellContaining(worldRenderer.Position(TopLeft)).ToMPos(map);
|
||||||
clamp = map.MapTiles.Value.Clamp;
|
var br = map.CellContaining(worldRenderer.Position(BottomRight)).ToMPos(map);
|
||||||
|
|
||||||
// Due to diamond tile staggering, we need to adjust the top-left bounds outwards by half a cell.
|
// Diamond tile shapes don't have straight edges, and so we need
|
||||||
|
// an additional cell margin to include the cells that are half
|
||||||
|
// visible on each edge.
|
||||||
if (map.TileShape == TileShape.Diamond)
|
if (map.TileShape == TileShape.Diamond)
|
||||||
wtl -= new WVec(512, 512, 0);
|
{
|
||||||
|
tl = new MPos(tl.U - 1, tl.V - 1);
|
||||||
|
br = new MPos(br.U + 1, br.V + 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Visible rectangle in map coordinates.
|
// Clamp to the visible map bounds, if requested
|
||||||
var dy = map.TileShape == TileShape.Diamond ? 512 : 1024;
|
if (insideBounds)
|
||||||
var ctl = new MPos(wtl.X / 1024, wtl.Y / dy);
|
{
|
||||||
var cbr = new MPos(wbr.X / 1024, wbr.Y / dy);
|
tl = map.Clamp(tl);
|
||||||
|
br = map.Clamp(br);
|
||||||
|
}
|
||||||
|
|
||||||
var tl = clamp(ctl).ToCPos(map.TileShape);
|
// Cells can be pushed up from below if they have non-zero height.
|
||||||
|
// Each height step is equivalent to 512 WRange units, which is
|
||||||
|
// one MPos step for diamond cells, but only half a MPos step
|
||||||
|
// for classic cells. Doh!
|
||||||
|
var heightOffset = map.TileShape == TileShape.Diamond ? maxGroundHeight : maxGroundHeight / 2;
|
||||||
|
br = new MPos(br.U, br.V + heightOffset);
|
||||||
|
|
||||||
// Also need to account for height of cells in rows below the bottom.
|
// Finally, make sure that this region doesn't extend outside the map area.
|
||||||
var heightPadding = map.TileShape == TileShape.Diamond ? 3 : 0;
|
tl = map.MapHeight.Value.Clamp(tl);
|
||||||
var br = clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2 + 1)).ToCPos(map.TileShape);
|
br = map.MapHeight.Value.Clamp(br);
|
||||||
|
|
||||||
return new CellRegion(map.TileShape, tl, br);
|
return new CellRegion(map.TileShape, tl.ToCPos(map), br.ToCPos(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CellRegion VisibleCellsInsideBounds
|
public CellRegion VisibleCellsInsideBounds
|
||||||
|
|||||||
Reference in New Issue
Block a user