Add IModel.AggregateBounds and ModelAnimation.ScreenBounds.
The bounds define the smallest Rectangle that covers all rotations of all frames within a model sequence.
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
|
|
||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
@@ -23,6 +24,9 @@ namespace OpenRA.Graphics
|
|||||||
float[] Size { get; }
|
float[] Size { get; }
|
||||||
float[] Bounds(uint frame);
|
float[] Bounds(uint frame);
|
||||||
ModelRenderData RenderData(uint section);
|
ModelRenderData RenderData(uint section);
|
||||||
|
|
||||||
|
/// <summary>Returns the smallest rectangle that covers all rotations of all frames in a model</summary>
|
||||||
|
Rectangle AggregateBounds { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ModelRenderData
|
public struct ModelRenderData
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
{
|
{
|
||||||
@@ -33,6 +34,19 @@ namespace OpenRA.Graphics
|
|||||||
ShowShadow = showshadow;
|
ShowShadow = showshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rectangle ScreenBounds(WPos pos, WorldRenderer wr, float scale)
|
||||||
|
{
|
||||||
|
var r = Model.AggregateBounds;
|
||||||
|
var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero;
|
||||||
|
var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset);
|
||||||
|
|
||||||
|
return Rectangle.FromLTRB(
|
||||||
|
xy.X + (int)(r.Left * scale),
|
||||||
|
xy.Y + (int)(r.Top * scale),
|
||||||
|
xy.X + (int)(r.Right * scale),
|
||||||
|
xy.Y + (int)(r.Bottom * scale));
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsVisible
|
public bool IsVisible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Mods.Cnc.FileFormats;
|
using OpenRA.Mods.Cnc.FileFormats;
|
||||||
@@ -125,5 +126,33 @@ namespace OpenRA.Mods.Cnc.Graphics
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rectangle AggregateBounds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Corner offsets
|
||||||
|
var ix = new uint[] { 0, 0, 0, 0, 3, 3, 3, 3 };
|
||||||
|
var iy = new uint[] { 1, 1, 4, 4, 1, 1, 4, 4 };
|
||||||
|
var iz = new uint[] { 2, 5, 2, 5, 2, 5, 2, 5 };
|
||||||
|
|
||||||
|
// Calculate the smallest sphere that covers the model limbs
|
||||||
|
var rSquared = 0f;
|
||||||
|
for (var f = 0U; f < frames; f++)
|
||||||
|
{
|
||||||
|
var bounds = Bounds(f);
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
var x = bounds[ix[i]];
|
||||||
|
var y = bounds[iy[i]];
|
||||||
|
var z = bounds[iz[i]];
|
||||||
|
rSquared = Math.Max(rSquared, x * x + y * y + z * z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = (int)Math.Sqrt(rSquared) + 1;
|
||||||
|
return Rectangle.FromLTRB(-r, -r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user