Add support for only rendering effects inside screen bounds
This commit is contained in:
committed by
Paul Chote
parent
8ca43e3d6b
commit
1aebf9857c
@@ -20,5 +20,8 @@ namespace OpenRA.Effects
|
||||
IEnumerable<IRenderable> Render(WorldRenderer r);
|
||||
}
|
||||
|
||||
// Identifier interface for effects that are added to ScreenMap
|
||||
public interface ISpatiallyPartitionable { }
|
||||
|
||||
public interface IEffectAboveShroud { IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr); }
|
||||
}
|
||||
|
||||
@@ -110,7 +110,13 @@ namespace OpenRA.Graphics
|
||||
if (World.OrderGenerator != null)
|
||||
worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World));
|
||||
|
||||
worldRenderables = worldRenderables.Concat(World.Effects.SelectMany(e => e.Render(this)));
|
||||
// Unpartitioned effects
|
||||
worldRenderables = worldRenderables.Concat(World.UnpartitionedEffects.SelectMany(e => e.Render(this)));
|
||||
|
||||
// Partitioned, currently on-screen effects
|
||||
var effectRenderables = World.ScreenMap.EffectsInBox(Viewport.TopLeft, Viewport.BottomRight);
|
||||
worldRenderables = worldRenderables.Concat(effectRenderables.SelectMany(e => e.Render(this)));
|
||||
|
||||
worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey);
|
||||
|
||||
Game.Renderer.WorldModelRenderer.BeginFrame();
|
||||
|
||||
@@ -51,10 +51,15 @@ namespace OpenRA.Primitives
|
||||
MutateBins(item, itemBounds[item] = bounds, addItem);
|
||||
}
|
||||
|
||||
public void Remove(T item)
|
||||
public bool Remove(T item)
|
||||
{
|
||||
MutateBins(item, itemBounds[item], removeItem);
|
||||
Rectangle bounds;
|
||||
if (!itemBounds.TryGetValue(item, out bounds))
|
||||
return false;
|
||||
|
||||
MutateBins(item, bounds, removeItem);
|
||||
itemBounds.Remove(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
Dictionary<T, Rectangle> BinAt(int row, int col)
|
||||
|
||||
@@ -13,6 +13,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
@@ -33,6 +34,7 @@ namespace OpenRA.Traits
|
||||
readonly Func<Actor, bool> actorIsInWorld = a => a.IsInWorld;
|
||||
readonly Cache<Player, SpatiallyPartitioned<FrozenActor>> partitionedFrozenActors;
|
||||
readonly SpatiallyPartitioned<Actor> partitionedActors;
|
||||
readonly SpatiallyPartitioned<IEffect> partitionedEffects;
|
||||
WorldRenderer worldRenderer;
|
||||
|
||||
public ScreenMap(World world, ScreenMapInfo info)
|
||||
@@ -43,6 +45,7 @@ namespace OpenRA.Traits
|
||||
partitionedFrozenActors = new Cache<Player, SpatiallyPartitioned<FrozenActor>>(
|
||||
_ => new SpatiallyPartitioned<FrozenActor>(width, height, info.BinSize));
|
||||
partitionedActors = new SpatiallyPartitioned<Actor>(width, height, info.BinSize);
|
||||
partitionedEffects = new SpatiallyPartitioned<IEffect>(width, height, info.BinSize);
|
||||
}
|
||||
|
||||
public void WorldLoaded(World w, WorldRenderer wr) { worldRenderer = wr; }
|
||||
@@ -88,6 +91,37 @@ namespace OpenRA.Traits
|
||||
partitionedActors.Remove(a);
|
||||
}
|
||||
|
||||
public void Add(IEffect effect, WPos position, Size size)
|
||||
{
|
||||
var screenPos = worldRenderer.ScreenPxPosition(position);
|
||||
var screenBounds = new Rectangle(screenPos.X - size.Width / 2, screenPos.Y - size.Height / 2, size.Width, size.Height);
|
||||
partitionedEffects.Add(effect, screenBounds);
|
||||
}
|
||||
|
||||
public void Add(IEffect effect, WPos position, Sprite sprite)
|
||||
{
|
||||
var size = new Size((int)sprite.Size.X, (int)sprite.Size.Y);
|
||||
Add(effect, position, size);
|
||||
}
|
||||
|
||||
public void Update(IEffect effect, WPos position, Size size)
|
||||
{
|
||||
var screenPos = worldRenderer.ScreenPxPosition(position);
|
||||
var screenBounds = new Rectangle(screenPos.X - size.Width / 2, screenPos.Y - size.Height / 2, size.Width, size.Height);
|
||||
partitionedEffects.Update(effect, screenBounds);
|
||||
}
|
||||
|
||||
public void Update(IEffect effect, WPos position, Sprite sprite)
|
||||
{
|
||||
var size = new Size((int)sprite.Size.X, (int)sprite.Size.Y);
|
||||
Update(effect, position, size);
|
||||
}
|
||||
|
||||
public void Remove(IEffect e)
|
||||
{
|
||||
partitionedEffects.Remove(e);
|
||||
}
|
||||
|
||||
public IEnumerable<FrozenActor> FrozenActorsAt(Player viewer, int2 worldPx)
|
||||
{
|
||||
if (viewer == null)
|
||||
@@ -120,6 +154,11 @@ namespace OpenRA.Traits
|
||||
return ActorsInBox(RectWithCorners(a, b));
|
||||
}
|
||||
|
||||
public IEnumerable<IEffect> EffectsInBox(int2 a, int2 b)
|
||||
{
|
||||
return partitionedEffects.InBox(RectWithCorners(a, b));
|
||||
}
|
||||
|
||||
public IEnumerable<Actor> ActorsInBox(Rectangle r)
|
||||
{
|
||||
return partitionedActors.InBox(r).Where(actorIsInWorld);
|
||||
@@ -130,6 +169,11 @@ namespace OpenRA.Traits
|
||||
return FrozenActorsInBox(p, RectWithCorners(a, b));
|
||||
}
|
||||
|
||||
public IEnumerable<IEffect> EffectsInBox(Rectangle r)
|
||||
{
|
||||
return partitionedEffects.InBox(r);
|
||||
}
|
||||
|
||||
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, Rectangle r)
|
||||
{
|
||||
if (p == null)
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace OpenRA
|
||||
internal readonly TraitDictionary TraitDict = new TraitDictionary();
|
||||
readonly SortedDictionary<uint, Actor> actors = new SortedDictionary<uint, Actor>();
|
||||
readonly List<IEffect> effects = new List<IEffect>();
|
||||
readonly List<IEffect> unpartitionedEffects = new List<IEffect>();
|
||||
readonly List<ISync> syncedEffects = new List<ISync>();
|
||||
|
||||
readonly Queue<Action<World>> frameEndActions = new Queue<Action<World>>();
|
||||
@@ -285,6 +286,11 @@ namespace OpenRA
|
||||
public void Add(IEffect e)
|
||||
{
|
||||
effects.Add(e);
|
||||
|
||||
var sp = e as ISpatiallyPartitionable;
|
||||
if (sp == null)
|
||||
unpartitionedEffects.Add(e);
|
||||
|
||||
var se = e as ISync;
|
||||
if (se != null)
|
||||
syncedEffects.Add(se);
|
||||
@@ -293,6 +299,11 @@ namespace OpenRA
|
||||
public void Remove(IEffect e)
|
||||
{
|
||||
effects.Remove(e);
|
||||
|
||||
var sp = e as ISpatiallyPartitionable;
|
||||
if (sp == null)
|
||||
unpartitionedEffects.Remove(e);
|
||||
|
||||
var se = e as ISync;
|
||||
if (se != null)
|
||||
syncedEffects.Remove(se);
|
||||
@@ -301,6 +312,7 @@ namespace OpenRA
|
||||
public void RemoveAll(Predicate<IEffect> predicate)
|
||||
{
|
||||
effects.RemoveAll(predicate);
|
||||
unpartitionedEffects.RemoveAll(e => predicate((IEffect)e));
|
||||
syncedEffects.RemoveAll(e => predicate((IEffect)e));
|
||||
}
|
||||
|
||||
@@ -361,6 +373,7 @@ namespace OpenRA
|
||||
|
||||
public IEnumerable<Actor> Actors { get { return actors.Values; } }
|
||||
public IEnumerable<IEffect> Effects { get { return effects; } }
|
||||
public IEnumerable<IEffect> UnpartitionedEffects { get { return unpartitionedEffects; } }
|
||||
public IEnumerable<ISync> SyncedEffects { get { return syncedEffects; } }
|
||||
|
||||
public Actor GetActorById(uint actorId)
|
||||
|
||||
Reference in New Issue
Block a user