Add conversions and helpers for world coordinates.

This commit is contained in:
Paul Chote
2013-03-12 05:52:30 +13:00
parent 724ea88c3b
commit 9e4bab07e5
5 changed files with 89 additions and 2 deletions

View File

@@ -28,6 +28,8 @@ namespace OpenRA
Lazy<IOccupySpace> occupySpace;
IHasLocation HasLocation;
Lazy<IMove> Move;
Lazy<IFacing> Facing;
public Cached<Rectangle> Bounds;
public Cached<Rectangle> ExtendedBounds;
@@ -45,6 +47,25 @@ namespace OpenRA
}
}
public WPos CenterPosition
{
get
{
var altitude = Move.Value != null ? Move.Value.Altitude : 0;
return CenterLocation.ToWPos(altitude);
}
}
public WRot Orientation
{
get
{
// TODO: Support non-zero pitch/roll in IFacing (IOrientation?)
var facing = Facing.Value != null ? Facing.Value.Facing : 0;
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing));
}
}
public Shroud.ActorVisibility Sight;
[Sync] public Player Owner;
@@ -74,6 +95,7 @@ namespace OpenRA
}
Move = Lazy.New(() => TraitOrDefault<IMove>());
Facing = Lazy.New(() => TraitOrDefault<IFacing>());
Size = Lazy.New(() =>
{

View File

@@ -211,5 +211,25 @@ namespace OpenRA.Graphics
{
palette.Update( world.WorldActor.TraitsImplementing<IPaletteModifier>() );
}
// Conversion between world and screen coordinates
public float2 ScreenPosition(WPos pos)
{
var c = Game.CellSize/1024f;
return new float2(c*pos.X, c*(pos.Y - pos.Z));
}
public int2 ScreenPxPosition(WPos pos)
{
var c = Game.CellSize/1024f;
return new int2((int)(c*pos.X), (int)(c*(pos.Y - pos.Z)));
}
public float ScreenZOffset(WPos pos) { return pos.Z*Game.CellSize/1024f; }
public float[] ScreenOffset(WVec vec)
{
var c = Game.CellSize/1024f;
return new float[] {c*vec.X, c*vec.Y, c*vec.Z};
}
}
}

View File

@@ -23,6 +23,18 @@ namespace OpenRA
public PPos(int x, int y) { X = x; Y = y; }
public static readonly PPos Zero = new PPos(0, 0);
public static PPos FromWPos(WPos pos)
{
return new PPos(Game.CellSize*pos.X/1024, Game.CellSize*pos.Y/1024);
}
// Temporary hack for things that throw away altitude and
// cache screen positions directly. This can go once all
// the callers understand world coordinates
public static PPos FromWPosHackZ(WPos pos)
{
return new PPos(Game.CellSize*pos.X/1024, Game.CellSize*(pos.Y - pos.Z)/1024);
}
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
@@ -74,6 +86,13 @@ namespace OpenRA
Math.Min(r.Bottom, Math.Max(Y, r.Top)));
}
public WPos ToWPos(int z)
{
return new WPos(1024*X/Game.CellSize,
1024*Y/Game.CellSize,
1024*z/Game.CellSize);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)

View File

@@ -27,6 +27,10 @@ namespace OpenRA.Traits
[Desc("Change the sprite image size.")]
public readonly float Scale = 1f;
[Desc("Number of facings for gameplay calculations. -1 indiciates auto-detection from sequence")]
public readonly int QuantizedFacings = -1;
public readonly WAngle CameraPitch = WAngle.FromDegrees(40);
public virtual object Create(ActorInitializer init) { return new RenderSimple(init.self); }
public virtual IEnumerable<Renderable> RenderPreview(ActorInfo building, PaletteReference pr)
@@ -38,7 +42,7 @@ namespace OpenRA.Traits
}
}
public class RenderSimple : IRender, IAutoSelectionSize, ITick, INotifyOwnerChanged
public class RenderSimple : IRender, ILocalCoordinatesModel, IAutoSelectionSize, ITick, INotifyOwnerChanged
{
public Dictionary<string, AnimationWithOffset> anims = new Dictionary<string, AnimationWithOffset>();
@@ -140,5 +144,22 @@ namespace OpenRA.Traits
anim.PlayThen(NormalizeSequence(self, name),
() => anim.PlayRepeating(NormalizeSequence(self, "idle")));
}
public WVec LocalToWorld(WVec vec)
{
// RA's 2d perspective doesn't correspond to an orthonormal 3D
// coordinate system, so fudge the y axis to make things look good
return new WVec(vec.Y, -Info.CameraPitch.Sin()*vec.X/1024, vec.Z);
}
public WRot QuantizeOrientation(Actor self, WRot orientation)
{
// Map yaw to the closest facing
var numDirs = Info.QuantizedFacings == -1 ? anim.CurrentSequence.Facings : Info.QuantizedFacings;
var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, numDirs) * (256 / numDirs);
// Roll and pitch are always zero
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing));
}
}
}

View File

@@ -211,6 +211,11 @@ namespace OpenRA.Traits
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr); }
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(WorldRenderer wr, Actor self); }
public interface ILocalCoordinatesModel
{
WVec LocalToWorld(WVec vec);
WRot QuantizeOrientation(Actor self, WRot orientation);
}
public interface ITargetable
{