diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 9bfea02aa..7ed4ec1aa 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -888,6 +888,11 @@ namespace Barotrauma } } + public override bool IsVisible(Rectangle worldView) + { + return drawableComponents.Count > 0 || body == null || body.Enabled; + } + public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { if (!Visible) return; diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 6d4389503..84f82987c 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -319,6 +319,11 @@ namespace Barotrauma mapEntityList.Insert(i, this); } + public virtual bool IsVisible(Rectangle worldView) + { + return true; + } + public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back=true) {} public virtual void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect) {} diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 747b3fae9..77c998493 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -475,6 +475,15 @@ namespace Barotrauma if (convexHulls != null) convexHulls.ForEach(x => x.Remove()); } + public override bool IsVisible(Rectangle WorldView) + { + Rectangle worldRect = WorldRect; + + if (worldRect.X > WorldView.Right || worldRect.Right < WorldView.X) return false; + if (worldRect.Y < WorldView.Y - WorldView.Height || worldRect.Y - worldRect.Height > WorldView.Y) return false; + + return true; + } public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { @@ -514,7 +523,7 @@ namespace Barotrauma spriteBatch, new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), new Vector2(rect.Width, rect.Height), - Vector2.Zero, color, Point.Zero); + color, Point.Zero); } } @@ -553,7 +562,7 @@ namespace Barotrauma spriteBatch, new Vector2(sections[i].rect.X + drawOffset.X, -(sections[i].rect.Y + drawOffset.Y)), new Vector2(sections[i].rect.Width, sections[i].rect.Height), - Vector2.Zero, color, + color, textureOffset, depth); } } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 74ae8cbff..0f13f4763 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -289,10 +289,10 @@ namespace Barotrauma } //drawing ---------------------------------------------------- - + public static void CullEntities(Camera cam) { - List visibleSubs = new List(); + HashSet visibleSubs = new HashSet(); foreach (Submarine sub in Submarine.Loaded) { Rectangle worldBorders = new Rectangle( @@ -301,19 +301,20 @@ namespace Barotrauma sub.Borders.Width + 1000, sub.Borders.Height + 1000); - if (Submarine.RectsOverlap(worldBorders, cam.WorldView)) { visibleSubs.Add(sub); } } + Rectangle worldView = cam.WorldView; + visibleEntities = new List(); foreach (MapEntity me in MapEntity.mapEntityList) { if (me.Submarine == null || visibleSubs.Contains(me.Submarine)) { - visibleEntities.Add(me); + if (me.IsVisible(worldView)) visibleEntities.Add(me); } } } diff --git a/Subsurface/Source/Sprite.cs b/Subsurface/Source/Sprite.cs index f427ff169..0788538fd 100644 --- a/Subsurface/Source/Sprite.cs +++ b/Subsurface/Source/Sprite.cs @@ -223,79 +223,79 @@ namespace Barotrauma DrawTiled(spriteBatch, pos, targetSize, Vector2.Zero, color); } - public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color, Point offset, float? overrideDepth = null) + public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Color color, Point offset, float? overrideDepth = null) { //how many times the texture needs to be drawn on the x-axis - int xTiles = (int)Math.Ceiling((targetSize.X + startOffset.X) / sourceRect.Width); + int xTiles = (int)Math.Ceiling(targetSize.X / sourceRect.Width); //how many times the texture needs to be drawn on the y-axis - int yTiles = (int)Math.Ceiling((targetSize.Y + startOffset.Y) / sourceRect.Height); + int yTiles = (int)Math.Ceiling(targetSize.Y / sourceRect.Height); float depth = overrideDepth == null ? this.depth : (float)overrideDepth; - + Rectangle texPerspective = sourceRect; texPerspective.Location += offset; - while (texPerspective.Location.X >= sourceRect.X + sourceRect.Width) - texPerspective.X = sourceRect.X + (texPerspective.Location.X - (sourceRect.X + sourceRect.Width)); - while (texPerspective.Location.Y >= sourceRect.Y + sourceRect.Height) - texPerspective.Y = sourceRect.Y + (texPerspective.Location.Y - (sourceRect.Y + sourceRect.Height)); + while (texPerspective.X >= sourceRect.Right) + texPerspective.X = sourceRect.X + (texPerspective.X - sourceRect.Right); + while (texPerspective.Y >= sourceRect.Bottom) + texPerspective.Y = sourceRect.Y + (texPerspective.Y - sourceRect.Bottom); - texPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width); + float top = pos.Y; texPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height); + for (int y = 0; y < yTiles; y++) { + var movementY = texPerspective.Height; + texPerspective.Height = Math.Min((int)(targetSize.Y - texPerspective.Height * y), texPerspective.Height); + + float left = pos.X; texPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width); - texPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height); - float top = pos.Y + texPerspective.Height * y; + for (int x = 0; x < xTiles; x++) { - float left = pos.X + texPerspective.Width * x; - texPerspective.Width = Math.Min((int)(targetSize.X - texPerspective.Width * x), texPerspective.Width); - texPerspective.Height = Math.Min((int)(targetSize.Y - texPerspective.Height * y), texPerspective.Height); - var movementX = texPerspective.Width; - var movementY = texPerspective.Height; + texPerspective.Width = Math.Min((int)(targetSize.X - texPerspective.Width * x), texPerspective.Width); + if (texPerspective.Right > sourceRect.Right) { + int diff = texPerspective.Right - sourceRect.Right; if (effects.HasFlag(SpriteEffects.FlipHorizontally)) { - int diff = (texPerspective.X + texPerspective.Width) - (sourceRect.Right); - - spriteBatch.Draw(texture, - new Vector2(left, top), - new Rectangle(sourceRect.X, texPerspective.Y, diff, texPerspective.Height), + spriteBatch.Draw(texture, + new Vector2(left, top), + new Rectangle(sourceRect.X, texPerspective.Y, diff, texPerspective.Height), color, rotation, Vector2.Zero, 1.0f, effects, depth); - + texPerspective.Width -= diff; left += diff; } else { - float diff = (texPerspective.X + texPerspective.Width) - (sourceRect.X + sourceRect.Width); texPerspective.Width -= (int)diff; - spriteBatch.Draw(texture, - new Vector2(left + texPerspective.Width, top), - new Rectangle(sourceRect.X, texPerspective.Y, (int)diff, texPerspective.Height), - color, rotation, Vector2.Zero, 1.0f, effects, depth); + spriteBatch.Draw(texture, + new Vector2(left + texPerspective.Width, top), + new Rectangle(sourceRect.X, texPerspective.Y, (int)diff, texPerspective.Height), + color, rotation, Vector2.Zero, 1.0f, effects, depth); } } else if (texPerspective.Bottom > sourceRect.Bottom) { - int diff = (texPerspective.Bottom) - (sourceRect.Bottom); + int diff = texPerspective.Bottom - sourceRect.Bottom; texPerspective.Height -= diff; - spriteBatch.Draw(texture, - new Vector2(left, top + texPerspective.Height), - new Rectangle(texPerspective.X, sourceRect.Y, texPerspective.Width, diff), + spriteBatch.Draw(texture, + new Vector2(left, top + texPerspective.Height), + new Rectangle(texPerspective.X, sourceRect.Y, texPerspective.Width, diff), color, rotation, Vector2.Zero, 1.0f, effects, depth); } spriteBatch.Draw(texture, new Vector2(left, top), texPerspective, color, rotation, Vector2.Zero, 1.0f, effects, depth); - if (texPerspective.X + movementX >= sourceRect.Right) - texPerspective.X = sourceRect.X; - if (texPerspective.Y + movementY >= sourceRect.Y + sourceRect.Height) - texPerspective.Y = sourceRect.Y; + if (texPerspective.X + movementX >= sourceRect.Right) texPerspective.X = sourceRect.X; + left += movementX; } + + if (texPerspective.Y + movementY >= sourceRect.Bottom) texPerspective.Y = sourceRect.Y; + top += movementY; } }