From db1a27b071bbfc72be92efc6f9c1f758f45aaa32 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 10 Feb 2015 14:26:44 +0000 Subject: [PATCH] Introduce IFinalizedRenderable.ScreenBounds. --- OpenRA.Game/Graphics/Renderable.cs | 7 ++++ .../Graphics/SelectionBarsRenderable.cs | 1 + .../Graphics/SelectionBoxRenderable.cs | 1 + OpenRA.Game/Graphics/TargetLineRenderable.cs | 1 + OpenRA.Game/Graphics/UISpriteRenderable.cs | 6 ++++ OpenRA.Mods.Common/Graphics/BeamRenderable.cs | 1 + .../Graphics/ContrailRenderable.cs | 1 + .../Graphics/RangeCircleRenderable.cs | 1 + OpenRA.Mods.Common/Graphics/TextRenderable.cs | 2 ++ .../Graphics/VoxelRenderable.cs | 36 +++++++++++++++++++ OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs | 3 ++ 11 files changed, 60 insertions(+) diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index f8e010f829..33f2a30b7d 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -33,6 +33,7 @@ namespace OpenRA.Graphics { void Render(WorldRenderer wr); void RenderDebugGeometry(WorldRenderer wr); + Rectangle ScreenBounds(WorldRenderer wr); } public struct SpriteRenderable : IRenderable, IFinalizedRenderable @@ -85,5 +86,11 @@ namespace OpenRA.Graphics var offset = ScreenPosition(wr) + sprite.Offset; Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + sprite.Size, Color.Red); } + + public Rectangle ScreenBounds(WorldRenderer wr) + { + var offset = ScreenPosition(wr) + sprite.Offset; + return new Rectangle((int)offset.X, (int)offset.Y, (int)sprite.Size.X, (int)sprite.Size.Y); + } } } diff --git a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs index 39f3f282ad..9127ea3bae 100644 --- a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs +++ b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs @@ -153,5 +153,6 @@ namespace OpenRA.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Game/Graphics/SelectionBoxRenderable.cs b/OpenRA.Game/Graphics/SelectionBoxRenderable.cs index 2943bb2f1e..1b677553f8 100644 --- a/OpenRA.Game/Graphics/SelectionBoxRenderable.cs +++ b/OpenRA.Game/Graphics/SelectionBoxRenderable.cs @@ -67,5 +67,6 @@ namespace OpenRA.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Game/Graphics/TargetLineRenderable.cs b/OpenRA.Game/Graphics/TargetLineRenderable.cs index 7f488c724b..ad8adba6b6 100644 --- a/OpenRA.Game/Graphics/TargetLineRenderable.cs +++ b/OpenRA.Game/Graphics/TargetLineRenderable.cs @@ -56,5 +56,6 @@ namespace OpenRA.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Game/Graphics/UISpriteRenderable.cs b/OpenRA.Game/Graphics/UISpriteRenderable.cs index 8fe5abdc68..757fdc6485 100644 --- a/OpenRA.Game/Graphics/UISpriteRenderable.cs +++ b/OpenRA.Game/Graphics/UISpriteRenderable.cs @@ -55,5 +55,11 @@ namespace OpenRA.Graphics var offset = screenPos + sprite.Offset; Game.Renderer.LineRenderer.DrawRect(offset, offset + sprite.Size, Color.Red); } + + public Rectangle ScreenBounds(WorldRenderer wr) + { + var offset = screenPos + sprite.Offset; + return new Rectangle((int)offset.X, (int)offset.Y, (int)sprite.Size.X, (int)sprite.Size.Y); + } } } diff --git a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs index 23405793d0..ac024c4187 100644 --- a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs @@ -54,5 +54,6 @@ namespace OpenRA.Mods.Common.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs b/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs index 5f51c830b7..d1075be2cb 100644 --- a/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs @@ -86,6 +86,7 @@ namespace OpenRA.Mods.Common.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } // Array index modulo length int Index(int i) diff --git a/OpenRA.Mods.Common/Graphics/RangeCircleRenderable.cs b/OpenRA.Mods.Common/Graphics/RangeCircleRenderable.cs index e68d24f630..82cb05e07f 100644 --- a/OpenRA.Mods.Common/Graphics/RangeCircleRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/RangeCircleRenderable.cs @@ -53,5 +53,6 @@ namespace OpenRA.Mods.Common.Graphics } public void RenderDebugGeometry(WorldRenderer wr) { } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Mods.Common/Graphics/TextRenderable.cs b/OpenRA.Mods.Common/Graphics/TextRenderable.cs index 69323f4bb2..1fe6ee36bc 100644 --- a/OpenRA.Mods.Common/Graphics/TextRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/TextRenderable.cs @@ -55,5 +55,7 @@ namespace OpenRA.Mods.Common.Graphics var offset = wr.ScreenPxPosition(pos) - 0.5f * size; Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + size, Color.Red); } + + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } } } diff --git a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs index 568e393b11..9898862bf2 100644 --- a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -185,6 +186,41 @@ namespace OpenRA.Mods.Common.Graphics Game.Renderer.WorldLineRenderer.DrawLine(corners[2], corners[6], c, c); Game.Renderer.WorldLineRenderer.DrawLine(corners[3], corners[7], c, c); } + + public Rectangle ScreenBounds(WorldRenderer wr) + { + var pxOrigin = wr.ScreenPosition(voxel.pos); + var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc()); + var scaleTransform = Util.ScaleMatrix(voxel.scale, voxel.scale, voxel.scale); + var cameraTransform = Util.MakeFloatMatrix(voxel.camera.AsMatrix()); + + var minX = float.MaxValue; + var minY = float.MaxValue; + var maxX = float.MinValue; + var maxY = float.MinValue; + foreach (var v in draw) + { + var bounds = v.Voxel.Bounds(v.FrameFunc()); + var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, + (x, y) => Util.MatrixMultiply(x, Util.MakeFloatMatrix(y.AsMatrix()))); + + var pxOffset = wr.ScreenVector(v.OffsetFunc()); + var pxPos = pxOrigin + new float2(pxOffset[0], pxOffset[1]); + var screenTransform = Util.MatrixMultiply(cameraTransform, worldTransform); + + for (var i = 0; i < 8; i++) + { + var vec = new float[] { bounds[CornerXIndex[i]], bounds[CornerYIndex[i]], bounds[CornerZIndex[i]], 1 }; + var screen = Util.MatrixVectorMultiply(screenTransform, vec); + minX = Math.Min(minX, pxPos.X + screen[0]); + minY = Math.Min(minY, pxPos.Y + screen[1]); + maxX = Math.Max(maxX, pxPos.X + screen[0]); + maxY = Math.Max(maxY, pxPos.Y + screen[1]); + } + } + + return Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY); + } } } } diff --git a/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs b/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs index 069d8a280d..28d25da0ef 100644 --- a/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs +++ b/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using OpenRA.Graphics; @@ -75,6 +76,8 @@ namespace OpenRA.Mods.RA.Graphics cache.Do(c => c.Render(wr)); } + public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; } + public IEnumerable GenerateRenderables(WorldRenderer wr) { var bright = wr.World.Map.SequenceProvider.GetSequence(image, "bright");