Skip to content

Commit

Permalink
Merge pull request #5758 from pchote/cell-world-conversions
Browse files Browse the repository at this point in the history
Generalize cell/world coordinate conversions.
  • Loading branch information
Mailaender committed Jun 28, 2014
2 parents 2431c34 + d7f1b1c commit 7fa5171
Show file tree
Hide file tree
Showing 100 changed files with 289 additions and 298 deletions.
19 changes: 0 additions & 19 deletions OpenRA.Game/CPos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ public struct CPos : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBindin
public static CPos Max(CPos a, CPos b) { return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static CPos Min(CPos a, CPos b) { return new CPos(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }

public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }

public WPos CenterPosition { get { return new WPos(1024 * X + 512, 1024 * Y + 512, 0); } }
public WPos TopLeft { get { return new WPos(1024 * X, 1024 * Y, 0); } }
public WPos BottomRight { get { return new WPos(1024 * X + 1023, 1024 * Y + 1023, 0); } }

public CPos Clamp(Rectangle r)
{
return new CPos(Math.Min(r.Right, Math.Max(X, r.Left)),
Expand Down Expand Up @@ -108,16 +101,4 @@ public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)

#endregion
}

public static class RectangleExtensions
{
public static CPos TopLeftAsCPos(this Rectangle r) { return new CPos(r.Left, r.Top); }
public static CPos BottomRightAsCPos(this Rectangle r) { return new CPos(r.Right, r.Bottom); }
}

public static class WorldCoordinateExtensions
{
public static CPos ToCPos(this WPos a) { return new CPos(a.X / 1024, a.Y / 1024); }
public static CVec ToCVec(this WVec a) { return new CVec(a.X / 1024, a.Y / 1024); }
}
}
10 changes: 0 additions & 10 deletions OpenRA.Game/CVec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,8 @@ public struct CVec : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBindin
public readonly int X, Y;

public CVec(int x, int y) { X = x; Y = y; }
public CVec(Size p) { X = p.Width; Y = p.Height; }

public static readonly CVec Zero = new CVec(0, 0);

public static explicit operator CVec(int2 a) { return new CVec(a.X, a.Y); }
public static explicit operator CVec(float2 a) { return new CVec((int)a.X, (int)a.Y); }

public static CVec operator +(CVec a, CVec b) { return new CVec(a.X + b.X, a.Y + b.Y); }
public static CVec operator -(CVec a, CVec b) { return new CVec(a.X - b.X, a.Y - b.Y); }
public static CVec operator *(int a, CVec b) { return new CVec(a * b.X, a * b.Y); }
Expand All @@ -49,10 +44,6 @@ public struct CVec : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBindin
public int LengthSquared { get { return X * X + Y * Y; } }
public int Length { get { return (int)Math.Sqrt(LengthSquared); } }

public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2(X, Y); }
public WVec ToWVec() { return new WVec(X*1024, Y*1024, 0); }

public CVec Clamp(Rectangle r)
{
return new CVec(
Expand Down Expand Up @@ -122,7 +113,6 @@ public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
{
case "X": return X;
case "Y": return Y;
case "Facing": return Traits.Util.GetFacing(this, 0);
default: throw new LuaException("CVec does not define a member '{0}'".F(key));
}
}
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/GameRules/WeaponInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public bool IsValidAgainst(Target target, World world)

if (target.Type == TargetType.Terrain)
{
var cell = target.CenterPosition.ToCPos();
var cell = world.Map.CellContaining(target.CenterPosition);
if (!world.Map.Contains(cell))
return false;

Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Game/Graphics/ContrailRenderable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ public void Render(WorldRenderer wr)

// Start of the first line segment is the tail of the list - don't smooth it.
var curPos = trail[idx(next - skip - 1)];
var curCell = curPos.ToCPos();
var curCell = wr.world.Map.CellContaining(curPos);
var curColor = color;
for (var i = 0; i < length - skip - 4; i++)
{
var j = next - skip - i - 2;
var nextPos = Average(trail[idx(j)], trail[idx(j-1)], trail[idx(j-2)], trail[idx(j-3)]);
var nextCell = nextPos.ToCPos();
var nextCell = wr.world.Map.CellContaining(nextPos);
var nextColor = Exts.ColorLerp(i * 1f / (length - 4), color, Color.Transparent);

if (!world.FogObscures(curCell) && !world.FogObscures(nextCell))
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Graphics/TerrainRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public TerrainRenderer(World world, WorldRenderer wr)
foreach (var cell in map.Cells)
{
var tile = wr.Theater.TileSprite(map.MapTiles.Value[cell]);
var pos = wr.ScreenPosition(cell.CenterPosition) - 0.5f * tile.size;
var pos = wr.ScreenPosition(map.CenterOfCell(cell)) - 0.5f * tile.size;
Util.FastCreateQuad(vertices, pos, tile, terrainPalette, nv, tile.size);
nv += 4;
}
Expand Down
19 changes: 13 additions & 6 deletions OpenRA.Game/Graphics/Viewport.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,21 @@ public Viewport(WorldRenderer wr, Map map)

// Calculate map bounds in world-px
var b = map.Bounds;
var tl = wr.ScreenPxPosition(new CPos(b.Left, b.Top).TopLeft);
var br = wr.ScreenPxPosition(new CPos(b.Right, b.Bottom).BottomRight);

// Expand to corners of cells
var tl = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Left, b.Top)) - new WVec(512, 512, 0));
var br = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Right, b.Bottom)) + new WVec(511, 511, 0));
mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);

CenterLocation = (tl + br) / 2;
Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1;
}

public CPos ViewToWorld(int2 view)
{
return worldRenderer.world.Map.CellContaining(worldRenderer.Position(ViewToWorldPx(view)));
}

public int2 ViewToWorldPx(int2 view) { return (1f / Zoom * view.ToFloat2()).ToInt2() + TopLeft; }
public int2 WorldToViewPx(int2 world) { return (Zoom * (world - TopLeft).ToFloat2()).ToInt2(); }

Expand Down Expand Up @@ -131,8 +138,8 @@ public Rectangle ScissorBounds
{
get
{
var ctl = VisibleCells.TopLeft.TopLeft;
var cbr = VisibleCells.BottomRight.BottomRight;
var ctl = worldRenderer.world.Map.CenterOfCell(VisibleCells.TopLeft) - new WVec(512, 512, 0);
var cbr = worldRenderer.world.Map.CenterOfCell(VisibleCells.BottomRight) + new WVec(511, 511, 0);
var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl)).Clamp(ScreenClip);
var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr)).Clamp(ScreenClip);
return Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);
Expand All @@ -147,8 +154,8 @@ public CellRegion VisibleCells
{
// Calculate the intersection of the visible rectangle and the map.
var map = worldRenderer.world.Map;
var tl = map.Clamp(worldRenderer.Position(TopLeft).ToCPos() - new CVec(1, 1));
var br = map.Clamp(worldRenderer.Position(BottomRight).ToCPos());
var tl = map.Clamp(map.CellContaining(worldRenderer.Position(TopLeft)) - new CVec(1, 1));
var br = map.Clamp(map.CellContaining(worldRenderer.Position(BottomRight)));

cells = new CellRegion(tl, br);
cellsDirty = false;
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Game/Map/ActorInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public class TurretFacingInit : IActorInit<int>

public class LocationInit : IActorInit<CPos>
{
[FieldFromYamlKey] public readonly int2 value = int2.Zero;
[FieldFromYamlKey] public readonly CPos value = CPos.Zero;
public LocationInit() { }
public LocationInit(CPos init) { value = init.ToInt2(); }
public CPos Value(World world) { return (CPos)value; }
public LocationInit(CPos init) { value = init; }
public CPos Value(World world) { return value; }
}

public class SubCellInit : IActorInit<SubCell>
Expand Down
24 changes: 21 additions & 3 deletions OpenRA.Game/Map/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,25 @@ public byte[] SaveBinaryData()
return dataStream.ToArray();
}

public bool Contains(CPos xy) { return Bounds.Contains(xy.X, xy.Y); }
public bool Contains(CPos cell)
{
return Bounds.Contains(cell.X, cell.Y);
}

public WPos CenterOfCell(CPos c)
{
return new WPos(1024 * c.X + 512, 1024 * c.Y + 512, 0);
}

public CPos CellContaining(WPos pos)
{
return new CPos(pos.X / 1024, pos.Y / 1024);
}

public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
{
return Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing);
}

public void Resize(int width, int height) // editor magic.
{
Expand Down Expand Up @@ -604,8 +622,8 @@ public CPos ChooseRandomEdgeCell(MersenneTwister rand)

public WRange DistanceToEdge(WPos pos, WVec dir)
{
var tl = Bounds.TopLeftAsCPos().TopLeft;
var br = Bounds.BottomRightAsCPos().BottomRight;
var tl = CenterOfCell(new CPos(Bounds.Left, Bounds.Top)) - new WVec(512, 512, 0);
var br = CenterOfCell(new CPos(Bounds.Right, Bounds.Bottom)) + new WVec(511, 511, 0);
var x = dir.X == 0 ? int.MaxValue : ((dir.X < 0 ? tl.X : br.X) - pos.X) / dir.X;
var y = dir.Y == 0 ? int.MaxValue : ((dir.Y < 0 ? tl.Y : br.Y) - pos.Y) / dir.Y;
return new WRange(Math.Min(x, y) * dir.Length);
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Game/Network/Order.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ public byte[] Serialize()
if (TargetActor != null)
w.Write(UIntFromActor(TargetActor));
if (TargetLocation != CPos.Zero)
w.Write(TargetLocation.ToInt2());
w.Write(TargetLocation);
if (TargetString != null)
w.Write(TargetString);
if (ExtraLocation != CPos.Zero)
w.Write(ExtraLocation.ToInt2());
w.Write(ExtraLocation);
if (ExtraData != 0)
w.Write(ExtraData);

Expand Down
6 changes: 6 additions & 0 deletions OpenRA.Game/Network/OrderIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,11 @@ public static void Write(this BinaryWriter w, int2 p)
w.Write(p.X);
w.Write(p.Y);
}

public static void Write(this BinaryWriter w, CPos cell)
{
w.Write(cell.X);
w.Write(cell.Y);
}
}
}
6 changes: 3 additions & 3 deletions OpenRA.Game/Orders/UnitOrderGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
.Where(a => a.Info.Traits.Contains<ITargetableInfo>())
.WithHighestSelectionPriority();
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(xy);
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
}

var orders = world.Selection.Actors
Expand Down Expand Up @@ -76,7 +76,7 @@ public string GetCursor(World world, CPos xy, MouseInput mi)
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
.Where(a => a.Info.Traits.Contains<ITargetableInfo>())
.WithHighestSelectionPriority();
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(xy);
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
}

var orders = world.Selection.Actors
Expand All @@ -103,7 +103,7 @@ static UnitOrderResult OrderForUnit(Actor self, Target target, MouseInput mi)
.Select(x => new { Trait = trait, Order = x }))
.OrderByDescending(x => x.Order.OrderPriority))
{
var actorsAt = self.World.ActorMap.GetUnitsAt(target.CenterPosition.ToCPos()).ToList();
var actorsAt = self.World.ActorMap.GetUnitsAt(self.World.Map.CellContaining(target.CenterPosition)).ToList();

var modifiers = TargetModifiers.None;
if (mi.Modifiers.HasModifier(Modifiers.Ctrl))
Expand Down
6 changes: 3 additions & 3 deletions OpenRA.Game/Traits/Target.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public struct Target
int generation;

public static Target FromPos(WPos p) { return new Target { pos = p, type = TargetType.Terrain }; }
public static Target FromCell(CPos c) { return new Target { pos = c.CenterPosition, type = TargetType.Terrain }; }
public static Target FromOrder(Order o)
public static Target FromCell(World w, CPos c) { return new Target { pos = w.Map.CenterOfCell(c), type = TargetType.Terrain }; }
public static Target FromOrder(World w, Order o)
{
return o.TargetActor != null
? FromActor(o.TargetActor)
: FromCell(o.TargetLocation);
: FromCell(w, o.TargetLocation);
}

public static Target FromActor(Actor a)
Expand Down
13 changes: 4 additions & 9 deletions OpenRA.Game/Traits/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ public static int GetFacing(WVec d, int currentFacing)
return (angle / 4 - 0x40) & 0xFF;
}

public static int GetFacing(CVec d, int currentFacing)
{
return GetFacing(d.ToWVec(), currentFacing);
}

public static int GetNearestFacing(int facing, int desiredFacing)
{
var turn = desiredFacing - facing;
Expand All @@ -65,9 +60,9 @@ public static int QuantizeFacing(int facing, int numFrames)
return a / step;
}

public static WPos BetweenCells(CPos from, CPos to)
public static WPos BetweenCells(World w, CPos from, CPos to)
{
return WPos.Lerp(from.CenterPosition, to.CenterPosition, 1, 2);
return WPos.Lerp(w.Map.CenterOfCell(from), w.Map.CenterOfCell(to), 1, 2);
}

public static Activity SequenceActivities(params Activity[] acts)
Expand Down Expand Up @@ -138,9 +133,9 @@ public static IEnumerable<CPos> ExpandFootprint(IEnumerable<CPos> cells, bool al
return result.Keys;
}

public static IEnumerable<CPos> AdjacentCells(Target target)
public static IEnumerable<CPos> AdjacentCells(World w, Target target)
{
var cells = target.Positions.Select(p => p.ToCPos()).Distinct();
var cells = target.Positions.Select(p => w.Map.CellContaining(p)).Distinct();
return ExpandFootprint(cells, true);
}
}
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Traits/World/ResourceLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void Render(WorldRenderer wr)

var c = render[cell];
if (c.Sprite != null)
new SpriteRenderable(c.Sprite, cell.CenterPosition,
new SpriteRenderable(c.Sprite, wr.world.Map.CenterOfCell(cell),
WVec.Zero, -511, c.Type.Palette, 1f, true).Render(wr);
}
}
Expand Down
9 changes: 5 additions & 4 deletions OpenRA.Game/Traits/World/Shroud.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ void Invalidate()

static IEnumerable<CPos> FindVisibleTiles(World world, CPos position, WRange radius)
{
var map = world.Map;
var r = (radius.Range + 1023) / 1024;
var limit = radius.Range * radius.Range;
var pos = position.CenterPosition;
var pos = map.CenterOfCell(position);

foreach (var cell in world.Map.FindTilesInCircle(position, r))
if ((cell.CenterPosition - pos).HorizontalLengthSquared <= limit)
foreach (var cell in map.FindTilesInCircle(position, r))
if ((map.CenterOfCell(cell) - pos).HorizontalLengthSquared <= limit)
yield return cell;
}

Expand Down Expand Up @@ -180,7 +181,7 @@ public static IEnumerable<CPos> GetVisOrigins(Actor a)
return cells.Select(c => c.First);
}

return new[] { a.CenterPosition.ToCPos() };
return new[] { a.World.Map.CellContaining(a.CenterPosition) };
}

public void Explore(World world, CPos center, WRange range)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Game/Widgets/ViewportControllerWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public override void Draw()
public void UpdateMouseover()
{
TooltipType = WorldTooltipType.None;
var cell = worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos();
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
if (!world.Map.Contains(cell))
return;

Expand Down
5 changes: 2 additions & 3 deletions OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ void ApplyOrders(World world, int2 xy, MouseInput mi)
return;

var pos = worldRenderer.Position(xy);
var orders = world.OrderGenerator.Order(world, pos.ToCPos(), mi).ToArray();

var orders = world.OrderGenerator.Order(world, world.Map.CellContaining(pos), mi).ToArray();
world.PlayVoiceForOrders(orders);

var flashed = false;
Expand Down Expand Up @@ -180,7 +179,7 @@ public override string GetCursor(int2 screenPos)
var xy = worldRenderer.Viewport.ViewToWorldPx(screenPos);
var pos = worldRenderer.Position(xy);
var cell = pos.ToCPos();
var cell = World.Map.CellContaining(pos);
var mi = new MouseInput
{
Expand Down
13 changes: 1 addition & 12 deletions OpenRA.Game/WorldUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ namespace OpenRA
{
public static class WorldUtils
{
public static IEnumerable<Actor> FindActorsInBox(this World world, CPos tl, CPos br)
{
// TODO: Support diamond boxes for isometric maps?
return world.FindActorsInBox(tl.TopLeft, br.BottomRight);
}

public static IEnumerable<Actor> FindActorsInBox(this World world, WPos tl, WPos br)
{
return world.ActorMap.ActorsInBox(tl, br);
}

public static Actor ClosestTo(this IEnumerable<Actor> actors, Actor a)
{
return actors.ClosestTo(a.CenterPosition);
Expand All @@ -48,7 +37,7 @@ public static IEnumerable<Actor> FindActorsInCircle(this World world, WPos origi
// Target ranges are calculated in 2D, so ignore height differences
var vec = new WVec(r, r, WRange.Zero);
var rSq = r.Range*r.Range;
return world.FindActorsInBox(origin - vec, origin + vec).Where(
return world.ActorMap.ActorsInBox(origin - vec, origin + vec).Where(
a => (a.CenterPosition - origin).HorizontalLengthSquared <= rSq);
}
}
Expand Down
Loading

0 comments on commit 7fa5171

Please sign in to comment.