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);
|
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); }
|
public interface IEffectAboveShroud { IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,13 @@ namespace OpenRA.Graphics
|
|||||||
if (World.OrderGenerator != null)
|
if (World.OrderGenerator != null)
|
||||||
worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World));
|
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);
|
worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey);
|
||||||
|
|
||||||
Game.Renderer.WorldModelRenderer.BeginFrame();
|
Game.Renderer.WorldModelRenderer.BeginFrame();
|
||||||
|
|||||||
@@ -51,10 +51,15 @@ namespace OpenRA.Primitives
|
|||||||
MutateBins(item, itemBounds[item] = bounds, addItem);
|
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);
|
itemBounds.Remove(item);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<T, Rectangle> BinAt(int row, int col)
|
Dictionary<T, Rectangle> BinAt(int row, int col)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.Effects;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ namespace OpenRA.Traits
|
|||||||
readonly Func<Actor, bool> actorIsInWorld = a => a.IsInWorld;
|
readonly Func<Actor, bool> actorIsInWorld = a => a.IsInWorld;
|
||||||
readonly Cache<Player, SpatiallyPartitioned<FrozenActor>> partitionedFrozenActors;
|
readonly Cache<Player, SpatiallyPartitioned<FrozenActor>> partitionedFrozenActors;
|
||||||
readonly SpatiallyPartitioned<Actor> partitionedActors;
|
readonly SpatiallyPartitioned<Actor> partitionedActors;
|
||||||
|
readonly SpatiallyPartitioned<IEffect> partitionedEffects;
|
||||||
WorldRenderer worldRenderer;
|
WorldRenderer worldRenderer;
|
||||||
|
|
||||||
public ScreenMap(World world, ScreenMapInfo info)
|
public ScreenMap(World world, ScreenMapInfo info)
|
||||||
@@ -43,6 +45,7 @@ namespace OpenRA.Traits
|
|||||||
partitionedFrozenActors = new Cache<Player, SpatiallyPartitioned<FrozenActor>>(
|
partitionedFrozenActors = new Cache<Player, SpatiallyPartitioned<FrozenActor>>(
|
||||||
_ => new SpatiallyPartitioned<FrozenActor>(width, height, info.BinSize));
|
_ => new SpatiallyPartitioned<FrozenActor>(width, height, info.BinSize));
|
||||||
partitionedActors = new SpatiallyPartitioned<Actor>(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; }
|
public void WorldLoaded(World w, WorldRenderer wr) { worldRenderer = wr; }
|
||||||
@@ -88,6 +91,37 @@ namespace OpenRA.Traits
|
|||||||
partitionedActors.Remove(a);
|
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)
|
public IEnumerable<FrozenActor> FrozenActorsAt(Player viewer, int2 worldPx)
|
||||||
{
|
{
|
||||||
if (viewer == null)
|
if (viewer == null)
|
||||||
@@ -120,6 +154,11 @@ namespace OpenRA.Traits
|
|||||||
return ActorsInBox(RectWithCorners(a, b));
|
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)
|
public IEnumerable<Actor> ActorsInBox(Rectangle r)
|
||||||
{
|
{
|
||||||
return partitionedActors.InBox(r).Where(actorIsInWorld);
|
return partitionedActors.InBox(r).Where(actorIsInWorld);
|
||||||
@@ -130,6 +169,11 @@ namespace OpenRA.Traits
|
|||||||
return FrozenActorsInBox(p, RectWithCorners(a, b));
|
return FrozenActorsInBox(p, RectWithCorners(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IEffect> EffectsInBox(Rectangle r)
|
||||||
|
{
|
||||||
|
return partitionedEffects.InBox(r);
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, Rectangle r)
|
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, Rectangle r)
|
||||||
{
|
{
|
||||||
if (p == null)
|
if (p == null)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace OpenRA
|
|||||||
internal readonly TraitDictionary TraitDict = new TraitDictionary();
|
internal readonly TraitDictionary TraitDict = new TraitDictionary();
|
||||||
readonly SortedDictionary<uint, Actor> actors = new SortedDictionary<uint, Actor>();
|
readonly SortedDictionary<uint, Actor> actors = new SortedDictionary<uint, Actor>();
|
||||||
readonly List<IEffect> effects = new List<IEffect>();
|
readonly List<IEffect> effects = new List<IEffect>();
|
||||||
|
readonly List<IEffect> unpartitionedEffects = new List<IEffect>();
|
||||||
readonly List<ISync> syncedEffects = new List<ISync>();
|
readonly List<ISync> syncedEffects = new List<ISync>();
|
||||||
|
|
||||||
readonly Queue<Action<World>> frameEndActions = new Queue<Action<World>>();
|
readonly Queue<Action<World>> frameEndActions = new Queue<Action<World>>();
|
||||||
@@ -285,6 +286,11 @@ namespace OpenRA
|
|||||||
public void Add(IEffect e)
|
public void Add(IEffect e)
|
||||||
{
|
{
|
||||||
effects.Add(e);
|
effects.Add(e);
|
||||||
|
|
||||||
|
var sp = e as ISpatiallyPartitionable;
|
||||||
|
if (sp == null)
|
||||||
|
unpartitionedEffects.Add(e);
|
||||||
|
|
||||||
var se = e as ISync;
|
var se = e as ISync;
|
||||||
if (se != null)
|
if (se != null)
|
||||||
syncedEffects.Add(se);
|
syncedEffects.Add(se);
|
||||||
@@ -293,6 +299,11 @@ namespace OpenRA
|
|||||||
public void Remove(IEffect e)
|
public void Remove(IEffect e)
|
||||||
{
|
{
|
||||||
effects.Remove(e);
|
effects.Remove(e);
|
||||||
|
|
||||||
|
var sp = e as ISpatiallyPartitionable;
|
||||||
|
if (sp == null)
|
||||||
|
unpartitionedEffects.Remove(e);
|
||||||
|
|
||||||
var se = e as ISync;
|
var se = e as ISync;
|
||||||
if (se != null)
|
if (se != null)
|
||||||
syncedEffects.Remove(se);
|
syncedEffects.Remove(se);
|
||||||
@@ -301,6 +312,7 @@ namespace OpenRA
|
|||||||
public void RemoveAll(Predicate<IEffect> predicate)
|
public void RemoveAll(Predicate<IEffect> predicate)
|
||||||
{
|
{
|
||||||
effects.RemoveAll(predicate);
|
effects.RemoveAll(predicate);
|
||||||
|
unpartitionedEffects.RemoveAll(e => predicate((IEffect)e));
|
||||||
syncedEffects.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<Actor> Actors { get { return actors.Values; } }
|
||||||
public IEnumerable<IEffect> Effects { get { return effects; } }
|
public IEnumerable<IEffect> Effects { get { return effects; } }
|
||||||
|
public IEnumerable<IEffect> UnpartitionedEffects { get { return unpartitionedEffects; } }
|
||||||
public IEnumerable<ISync> SyncedEffects { get { return syncedEffects; } }
|
public IEnumerable<ISync> SyncedEffects { get { return syncedEffects; } }
|
||||||
|
|
||||||
public Actor GetActorById(uint actorId)
|
public Actor GetActorById(uint actorId)
|
||||||
|
|||||||
Reference in New Issue
Block a user