Added rotation logic to the renderer to enable the use of Interpolated Facings.
This commit is contained in:
committed by
Matthias Mailänder
parent
e060d6eb05
commit
a1a50d6c98
@@ -108,6 +108,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
int ISpriteSequence.Length => throw exception;
|
||||
int ISpriteSequence.Stride => throw exception;
|
||||
int ISpriteSequence.Facings => throw exception;
|
||||
int ISpriteSequence.InterpolatedFacings => throw exception;
|
||||
int ISpriteSequence.Tick => throw exception;
|
||||
int ISpriteSequence.ZOffset => throw exception;
|
||||
int ISpriteSequence.ShadowStart => throw exception;
|
||||
@@ -118,6 +119,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
float ISpriteSequence.Scale => throw exception;
|
||||
Sprite ISpriteSequence.GetSprite(int frame) { throw exception; }
|
||||
Sprite ISpriteSequence.GetSprite(int frame, WAngle facing) { throw exception; }
|
||||
(Sprite, WAngle) ISpriteSequence.GetSpriteWithRotation(int frame, WAngle facing) { throw exception; }
|
||||
Sprite ISpriteSequence.GetShadow(int frame, WAngle facing) { throw exception; }
|
||||
float ISpriteSequence.GetAlpha(int frame) { throw exception; }
|
||||
}
|
||||
@@ -167,6 +169,11 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
int ISpriteSequence.Facings => facings;
|
||||
protected int facings;
|
||||
|
||||
[Desc("The amount of directions the unit faces. Use negative values to rotate counter-clockwise.")]
|
||||
static readonly SpriteSequenceField<int> InterpolatedFacings = new SpriteSequenceField<int>(nameof(InterpolatedFacings), 1);
|
||||
int ISpriteSequence.InterpolatedFacings => interpolatedFacings;
|
||||
protected int interpolatedFacings;
|
||||
|
||||
[Desc("Time (in milliseconds at default game speed) to wait until playing the next frame in the animation.")]
|
||||
static readonly SpriteSequenceField<int> Tick = new SpriteSequenceField<int>(nameof(Tick), 40);
|
||||
int ISpriteSequence.Tick => tick;
|
||||
@@ -305,6 +312,11 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
var zRamp = LoadField(d, ZRamp);
|
||||
|
||||
facings = LoadField(d, Facings);
|
||||
interpolatedFacings = LoadField(d, nameof(InterpolatedFacings), -1);
|
||||
if (interpolatedFacings != -1 && (interpolatedFacings <= 1 || interpolatedFacings <= Math.Abs(facings) || interpolatedFacings > 1024
|
||||
|| !Exts.IsPowerOf2(interpolatedFacings)))
|
||||
throw new YamlException($"InterpolatedFacings must be greater than Facings, within the range of 2 to 1024, and a power of 2.");
|
||||
|
||||
if (facings < 0)
|
||||
{
|
||||
reverseFacings = true;
|
||||
@@ -531,6 +543,17 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
return GetSprite(start, frame, facing);
|
||||
}
|
||||
|
||||
public (Sprite, WAngle) GetSpriteWithRotation(int frame, WAngle facing)
|
||||
{
|
||||
var rotation = WAngle.Zero;
|
||||
|
||||
// Note: Error checking is not done here as it is done on load
|
||||
if (interpolatedFacings != -1)
|
||||
rotation = Util.GetInterpolatedFacing(facing, Math.Abs(facings), interpolatedFacings);
|
||||
|
||||
return (GetSprite(start, frame, facing), rotation);
|
||||
}
|
||||
|
||||
public Sprite GetShadow(int frame, WAngle facing)
|
||||
{
|
||||
return shadowStart >= 0 ? GetSprite(shadowStart, frame, facing) : null;
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
throw new InvalidOperationException("Actor " + ai.Name + " is missing sequence to quantize facings from.");
|
||||
|
||||
var rsi = ai.TraitInfo<RenderSpritesInfo>();
|
||||
return sequenceProvider.GetSequence(rsi.GetImage(ai, race), Sequence).Facings;
|
||||
var seq = sequenceProvider.GetSequence(rsi.GetImage(ai, race), Sequence);
|
||||
return seq.InterpolatedFacings == -1 ? seq.Facings : seq.InterpolatedFacings;
|
||||
}
|
||||
|
||||
public override object Create(ActorInitializer init) { return new QuantizeFacingsFromSequence(this); }
|
||||
|
||||
@@ -67,11 +67,28 @@ namespace OpenRA.Mods.Common
|
||||
/// </summary>
|
||||
public static int IndexFacing(WAngle facing, int numFrames)
|
||||
{
|
||||
// 1024 here is the max angle, so we divide the max angle by the total number of facings (numFrames)
|
||||
var step = 1024 / numFrames;
|
||||
var a = (facing.Angle + step / 2) & 1023;
|
||||
return a / step;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the remainder angle after rounding to the nearest whole step / facing
|
||||
/// </summary>
|
||||
public static WAngle AngleDiffToStep(WAngle facing, int numFrames)
|
||||
{
|
||||
var step = 1024 / numFrames;
|
||||
var a = (facing.Angle + step / 2) & 1023;
|
||||
return new WAngle(a % step - step / 2);
|
||||
}
|
||||
|
||||
public static WAngle GetInterpolatedFacing(WAngle facing, int facings, int interpolatedFacings)
|
||||
{
|
||||
var step = 1024 / interpolatedFacings;
|
||||
return new WAngle(AngleDiffToStep(facing, facings).Angle / step * step);
|
||||
}
|
||||
|
||||
/// <summary>Rounds the given facing value to the nearest quantized step.</summary>
|
||||
public static WAngle QuantizeFacing(WAngle facing, int steps)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user