Speed up depth sorting of renderables.
The OrderBy overload that takes an int generating key selector is faster than the one that requires a custom comparer. We extract a function from the ScreenZPosition function that determines the Z position of a WPos with an offset, but does not account for the tileset height. For the ordering function this is fine as only the relative magnitude of the comparison keys matter, so we don't need to spend time adjusting for the tileset height, as that won't affect the sort.
This commit is contained in:
@@ -14,22 +14,6 @@ using System.Linq;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public class RenderableComparer : IComparer<IRenderable>
|
||||
{
|
||||
WorldRenderer wr;
|
||||
public RenderableComparer(WorldRenderer wr)
|
||||
{
|
||||
this.wr = wr;
|
||||
}
|
||||
|
||||
public int Compare(IRenderable x, IRenderable y)
|
||||
{
|
||||
var xOrder = wr.ScreenZPosition(x.Pos, x.ZOffset);
|
||||
var yOrder = wr.ScreenZPosition(y.Pos, y.ZOffset);
|
||||
return xOrder.CompareTo(yOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IRenderable
|
||||
{
|
||||
WPos Pos { get; }
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace OpenRA.Graphics
|
||||
|
||||
public sealed class WorldRenderer : IDisposable
|
||||
{
|
||||
public static readonly Func<IRenderable, int> RenderableScreenZPositionComparisonKey =
|
||||
r => ZPosition(r.Pos, r.ZOffset);
|
||||
|
||||
public readonly World World;
|
||||
public readonly Theater Theater;
|
||||
public Viewport Viewport { get; private set; }
|
||||
@@ -69,7 +72,6 @@ namespace OpenRA.Graphics
|
||||
|
||||
List<IRenderable> GenerateRenderables()
|
||||
{
|
||||
var comparer = new RenderableComparer(this);
|
||||
var actors = World.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight)
|
||||
.Append(World.WorldActor)
|
||||
.ToList();
|
||||
@@ -82,7 +84,7 @@ namespace OpenRA.Graphics
|
||||
if (World.OrderGenerator != null)
|
||||
worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World));
|
||||
|
||||
worldRenderables = worldRenderables.OrderBy(r => r, comparer);
|
||||
worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey);
|
||||
|
||||
// Effects are drawn on top of all actors
|
||||
// HACK: Effects aren't interleaved with actors.
|
||||
@@ -241,7 +243,12 @@ namespace OpenRA.Graphics
|
||||
public float ScreenZPosition(WPos pos, int offset)
|
||||
{
|
||||
var ts = Game.ModData.Manifest.TileSize;
|
||||
return (pos.Y + pos.Z + offset) * ts.Height / 1024f;
|
||||
return ZPosition(pos, offset) * ts.Height / 1024f;
|
||||
}
|
||||
|
||||
static int ZPosition(WPos pos, int offset)
|
||||
{
|
||||
return pos.Y + pos.Z + offset;
|
||||
}
|
||||
|
||||
public WPos Position(int2 screenPx)
|
||||
|
||||
Reference in New Issue
Block a user