From 2b65392a3c2a3ff22a6505dc9035cffa8d3f3f09 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 29 Mar 2017 23:28:09 +0300 Subject: [PATCH] BackgroundSpriteManager takes the rotation and pivot point of the sprites into account when determining which cells of the "sprite grid" the sprite occupies (-> partially visible sprites shouldn't be culled away anymore) --- .../BackgroundSpriteManager.cs | 47 ++++++++++++++++--- .../BackgroundSpritePrefab.cs | 2 +- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index a8c6007b5..9236b2c73 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -18,6 +18,8 @@ namespace Barotrauma public float Scale; public float Rotation; + + //public Vector2[] spriteCorners; public BackgroundSprite(BackgroundSpritePrefab prefab, Vector3 position, float scale, float rotation = 0.0f) { @@ -68,6 +70,8 @@ namespace Barotrauma DebugConsole.ThrowError(String.Format("Failed to load BackgroundSprites from {0}", configPath), e); } } + + public void PlaceSprites(Level level, int amount) { sprites = new List[ @@ -101,15 +105,38 @@ namespace Barotrauma var newSprite = new BackgroundSprite(prefab, new Vector3((Vector2)pos, Rand.Range(prefab.DepthRange.X, prefab.DepthRange.Y, false)), Rand.Range(prefab.Scale.X, prefab.Scale.Y, false), rotation); + + //calculate the positions of the corners of the rotated sprite + Vector2 halfSize = newSprite.Prefab.Sprite.size * newSprite.Scale / 2; + var spriteCorners = new Vector2[] + { + -halfSize, new Vector2(-halfSize.X, halfSize.Y), + halfSize, new Vector2(halfSize.X, -halfSize.Y) + }; - Vector2 spriteSize = newSprite.Prefab.Sprite.size * newSprite.Scale; + Vector2 pivotOffset = newSprite.Prefab.Sprite.Origin * newSprite.Scale - halfSize; + pivotOffset.X = -pivotOffset.X; + pivotOffset = new Vector2( + (float)(pivotOffset.X * Math.Cos(-rotation) - pivotOffset.Y * Math.Sin(-rotation)), + (float)(pivotOffset.X * Math.Sin(-rotation) + pivotOffset.Y * Math.Cos(-rotation))); - int minX = (int)Math.Floor((newSprite.Position.X - spriteSize.X / 2 - newSprite.Position.Z) / GridSize); - int maxX = (int)Math.Floor((newSprite.Position.X + spriteSize.X / 2 + newSprite.Position.Z) / GridSize); + for (int j = 0; j < 4; j++) + { + spriteCorners[j] = new Vector2( + (float)(spriteCorners[j].X * Math.Cos(-rotation) - spriteCorners[j].Y * Math.Sin(-rotation)), + (float)(spriteCorners[j].X * Math.Sin(-rotation) + spriteCorners[j].Y * Math.Cos(-rotation))); + + spriteCorners[j] += (Vector2)pos + pivotOffset; + } + + //newSprite.spriteCorners = spriteCorners; + + int minX = (int)Math.Floor((spriteCorners.Min(c => c.X) - newSprite.Position.Z) / GridSize); + int maxX = (int)Math.Floor((spriteCorners.Max(c => c.X) + newSprite.Position.Z) / GridSize); if (minX < 0 || maxX >= sprites.GetLength(0)) continue; - int minY = (int)Math.Floor((newSprite.Position.Y - spriteSize.Y / 2 - newSprite.Position.Z) / GridSize); - int maxY = (int)Math.Floor((newSprite.Position.Y + spriteSize.Y / 2 + newSprite.Position.Z) / GridSize); + int minY = (int)Math.Floor((spriteCorners.Min(c => c.Y) - newSprite.Position.Z) / GridSize); + int maxY = (int)Math.Floor((spriteCorners.Max(c => c.Y) + newSprite.Position.Z) / GridSize); if (minY < 0 || maxY >= sprites.GetLength(1)) continue; for (int x = minX; x <= maxX; x++) @@ -266,7 +293,7 @@ namespace Barotrauma } foreach (BackgroundSprite sprite in visibleSprites) - { + { Vector2 camDiff = new Vector2(sprite.Position.X, sprite.Position.Y) - cam.WorldViewCenter; camDiff.Y = -camDiff.Y; @@ -279,6 +306,14 @@ namespace Barotrauma SpriteEffects.None, z); + /*for (int i = 0; i < 4; i++) + { + GUI.DrawLine(spriteBatch, + new Vector2(sprite.spriteCorners[i].X, -sprite.spriteCorners[i].Y), + new Vector2(sprite.spriteCorners[(i + 1) % 4].X, -sprite.spriteCorners[(i + 1) % 4].Y), + Color.White, 0, 5); + }*/ + if (GameMain.DebugDraw) { GUI.DrawRectangle(spriteBatch, new Vector2(sprite.Position.X, -sprite.Position.Y), new Vector2(10.0f, 10.0f), Color.Red, true); diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs index 1568b2caf..f3df1563d 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpritePrefab.cs @@ -43,7 +43,7 @@ namespace Barotrauma Scale.X = ToolBox.GetAttributeFloat(element, "minsize", 1.0f); Scale.Y = ToolBox.GetAttributeFloat(element, "maxsize", 1.0f); - DepthRange = ToolBox.GetAttributeVector2(element, "depthrange", Vector2.Zero); + DepthRange = ToolBox.GetAttributeVector2(element, "depthrange", new Vector2(0.0f, 1.0f)); AlignWithSurface = ToolBox.GetAttributeBool(element, "alignwithsurface", false);