From e3cd19b781d164ac4bd6e0116d2e6d7177d400c5 Mon Sep 17 00:00:00 2001 From: Regalis Date: Tue, 8 Nov 2016 22:22:49 +0200 Subject: [PATCH] Wire rendering optimization (angles & distances between nodes are only calculated when adding/removing nodes) --- .../Source/Items/Components/Signal/Wire.cs | 169 +++++++++--------- 1 file changed, 86 insertions(+), 83 deletions(-) diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index 5471772d4..02b29463a 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -10,6 +10,47 @@ namespace Barotrauma.Items.Components { class Wire : ItemComponent, IDrawableComponent { + class WireSection + { + private Vector2 start; + + private float angle; + private float length; + + public WireSection(Vector2 start, Vector2 end) + { + this.start = start; + + angle = MathUtils.VectorToAngle(end - start); + length = Vector2.Distance(start, end); + } + + public void Draw(SpriteBatch spriteBatch, Color color, Vector2 offset, float depth, float width = 0.3f) + { + spriteBatch.Draw(wireSprite.Texture, + new Vector2(start.X+offset.X, -(start.Y+offset.Y)), null, color, + -angle, + new Vector2(0.0f, wireSprite.size.Y / 2.0f), + new Vector2(length / wireSprite.Texture.Width, width), + SpriteEffects.None, + depth); + } + + public static void Draw(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float depth, float width = 0.3f) + { + start.Y = -start.Y; + end.Y = -end.Y; + + spriteBatch.Draw(wireSprite.Texture, + start, null, color, + MathUtils.VectorToAngle(end - start), + new Vector2(0.0f, wireSprite.size.Y / 2.0f), + new Vector2((Vector2.Distance(start, end)) / wireSprite.Texture.Width, width), + SpriteEffects.None, + depth); + } + } + const float nodeDistance = 32.0f; const float heightFromFloor = 128.0f; @@ -17,6 +58,9 @@ namespace Barotrauma.Items.Components public List Nodes; + private bool sectionsDirty; + private List sections; + Connection[] connections; private Vector2 newNodePos; @@ -39,22 +83,15 @@ namespace Barotrauma.Items.Components wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f)); wireSprite.Depth = 0.85f; } - + Nodes = new List(); + sections = new List(); connections = new Connection[2]; - + IsActive = false; } - public override void Move(Vector2 amount) - { - //for (int i = 0; i < Nodes.Count; i++) - //{ - // Nodes[i] += amount; - //} - } - public Connection OtherConnection(Connection connection) { if (connection == null) return null; @@ -125,25 +162,23 @@ namespace Barotrauma.Items.Components if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break; if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break; - - + if (i == 0) { - Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition); + Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition); } else { Nodes.Add(newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition); } - + break; } if (connections[0] != null && connections[1] != null) { - //List prevNodes = new List(Nodes); foreach (ItemComponent ic in item.components) { if (ic == this) continue; @@ -155,7 +190,6 @@ namespace Barotrauma.Items.Components IsActive = false; - //Nodes = prevNodes; CleanNodes(); } @@ -163,6 +197,8 @@ namespace Barotrauma.Items.Components if (!loading) Item.NewComponentEvent(this, true, true); + UpdateSections(); + return true; } @@ -192,23 +228,6 @@ namespace Barotrauma.Items.Components { if (Nodes.Count == 0) return; - //item.FindHull(); - - //Vector2 position = item.Position; - - //position.X = MathUtils.Round(item.Position.X, nodeDistance); - //if (item.CurrentHull == null) - //{ - // position.Y = MathUtils.Round(item.Position.Y, nodeDistance); - //} - //else - //{ - // position.Y -= item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; - // position.Y = Math.Max(MathUtils.Round(position.Y, nodeDistance), heightFromFloor); - // position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height; - //} - - Submarine sub = null; if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine; if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine; @@ -221,20 +240,6 @@ namespace Barotrauma.Items.Components } newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition; - - //if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10) - //{ - // nodes.Add(position); - - // item.NewComponentEvent(this, true); - //} - //else if (Math.Abs(position.Y - nodes[nodes.Count - 1].Y) > nodeDistance) - //{ - // nodes.Add(new Vector2(nodes[nodes.Count - 1].X, - // position.Y)); - - // item.NewComponentEvent(this, true); - //} } public override bool Use(float deltaTime, Character character = null) @@ -244,6 +249,8 @@ namespace Barotrauma.Items.Components if (newNodePos!= Vector2.Zero && Nodes.Count>0 && Vector2.Distance(newNodePos, Nodes[Nodes.Count - 1]) > nodeDistance) { Nodes.Add(newNodePos); + UpdateSections(); + Drawable = true; newNodePos = Vector2.Zero; @@ -256,6 +263,7 @@ namespace Barotrauma.Items.Components if (Nodes.Count > 1) { Nodes.RemoveAt(Nodes.Count - 1); + UpdateSections(); item.NewComponentEvent(this, true, true); } @@ -270,9 +278,20 @@ namespace Barotrauma.Items.Components return true; } + private void UpdateSections() + { + sections.Clear(); + + for (int i = 0; i < Nodes.Count-1; i++) + { + sections.Add(new WireSection(Nodes[i], Nodes[i + 1])); + } + } + private void ClearConnections() { Nodes.Clear(); + sections.Clear(); for (int i = 0; i < 2; i++) { @@ -292,8 +311,6 @@ namespace Barotrauma.Items.Components { if (Screen.Selected == GameMain.EditMapScreen) { - //position = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - Submarine.Loaded.Position;// Nodes[(int)selectedNodeIndex]; - position.X = MathUtils.Round(position.X, Submarine.GridSize.X / 2.0f); position.Y = MathUtils.Round(position.Y, Submarine.GridSize.Y / 2.0f); } @@ -349,35 +366,42 @@ namespace Barotrauma.Items.Components public void Draw(SpriteBatch spriteBatch, bool editing) { - //for (int i = 0; i < nodes.Count; i++) - //{ - // GUI.DrawRectangle(spriteBatch, new Rectangle((int)nodes[i].X, (int)-nodes[i].Y, 5, 5), Color.DarkGray, true, wireSprite.Depth - 0.01f); - //} - if (!Nodes.Any()) { Drawable = false; return; } + Vector2 drawOffset = Vector2.Zero; + if (item.Submarine != null) + { + drawOffset = item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition; + } + + float depth = wireSprite.Depth + ((item.ID % 100) * 0.00001f); + if (item.IsHighlighted) { - for (int i = 1; i < Nodes.Count; i++) + foreach (WireSection section in sections) { - DrawSection(spriteBatch, Nodes[i], Nodes[i - 1], Color.Gold, 0.5f); + section.Draw(spriteBatch, Color.Gold, drawOffset, depth, 0.5f); } } - for (int i = 1; i < Nodes.Count; i++) + foreach (WireSection section in sections) { - DrawSection(spriteBatch, Nodes[i], Nodes[i - 1], item.Color); + section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f); } - - + if (IsActive && Vector2.Distance(newNodePos, Nodes[Nodes.Count - 1]) > nodeDistance) { - DrawSection(spriteBatch, Nodes[Nodes.Count - 1], newNodePos, item.Color * 0.5f); - //nodes.Add(newNodePos); + WireSection.Draw( + spriteBatch, + new Vector2(Nodes[Nodes.Count - 1].X, Nodes[Nodes.Count - 1].Y) + drawOffset, + new Vector2(newNodePos.X, newNodePos.Y) + drawOffset, + item.Color * 0.5f, + depth, + 0.3f); } if (!editing || !PlayerInput.MouseInsideWindow || !GameMain.EditMapScreen.WiringMode) return; @@ -399,7 +423,6 @@ namespace Barotrauma.Items.Components continue; } - GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f); if (selectedNodeIndex == null && draggingWire == null)// && !MapEntity.SelectedAny) @@ -451,26 +474,6 @@ namespace Barotrauma.Items.Components } } - private void DrawSection(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float width = 0.3f) - { - if (item.Submarine != null) - { - start += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition; - end += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition; - } - - start.Y = -start.Y; - end.Y = -end.Y; - - spriteBatch.Draw(wireSprite.Texture, - start, null, color, - MathUtils.VectorToAngle(end - start), - new Vector2(0.0f, wireSprite.size.Y / 2.0f), - new Vector2((Vector2.Distance(start, end)) / wireSprite.Texture.Width, width), - SpriteEffects.None, - wireSprite.Depth + ((item.ID % 100) * 0.00001f)); - } - public override void FlipX() { for (int i = 0; i < Nodes.Count; i++)