From 1f94e174ef87edb731e092cf6cd455314e4f07ec Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Wed, 3 Apr 2019 16:25:31 +0300 Subject: [PATCH] (50a891840) Lazy deformable LevelObject sprite loading --- .../BarotraumaClient/Source/GameSettings.cs | 3 - .../Map/Levels/LevelObjects/LevelObject.cs | 1 + .../Source/Screens/LevelEditorScreen.cs | 5 ++ .../Source/Sprite/DeformableSprite.cs | 59 ++++++++++++++----- .../Items/Components/Signal/LightComponent.cs | 4 -- .../Levels/LevelObjects/LevelObjectPrefab.cs | 2 +- .../Source/Sprite/DeformableSprite.cs | 23 +++----- 7 files changed, 59 insertions(+), 38 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index cc675d441..bdccb59a7 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -664,9 +664,6 @@ namespace Barotrauma //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null); - //spacing - new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null); - new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft), TextManager.Get("Cancel"), style: "GUIButtonLarge") { diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs index 6ce5f1fb8..181e555c8 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs @@ -78,6 +78,7 @@ namespace Barotrauma { Prefab.Sprite?.EnsureLazyLoaded(); Prefab.SpecularSprite?.EnsureLazyLoaded(); + Prefab.DeformableSprite?.EnsureLazyLoaded(); CurrentSwingAmount = Prefab.SwingAmountRad; CurrentScaleOscillation = Prefab.ScaleOscillation; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs index 792ba1d17..ba8a40c79 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs @@ -172,6 +172,11 @@ namespace Barotrauma { base.Select(); + foreach (LevelObjectPrefab levelObjPrefab in LevelObjectPrefab.List) + { + levelObjPrefab.Sprite?.EnsureLazyLoaded(); + } + pointerLightSource = new LightSource(Vector2.Zero, 1000.0f, Color.White, submarine: null); GameMain.LightManager.AddLight(pointerLightSource); topPanel.ClearChildren(); diff --git a/Barotrauma/BarotraumaClient/Source/Sprite/DeformableSprite.cs b/Barotrauma/BarotraumaClient/Source/Sprite/DeformableSprite.cs index 54f33dbb6..537cdb93b 100644 --- a/Barotrauma/BarotraumaClient/Source/Sprite/DeformableSprite.cs +++ b/Barotrauma/BarotraumaClient/Source/Sprite/DeformableSprite.cs @@ -12,6 +12,8 @@ namespace Barotrauma { private static List list = new List(); + private bool initialized = false; + private int triangleCount; private VertexBuffer vertexBuffer, flippedVertexBuffer; @@ -34,7 +36,7 @@ namespace Barotrauma private Point spritePos; private Point spriteSize; - partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY) + partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY, bool lazyLoad) { if (effect == null) { @@ -56,11 +58,30 @@ namespace Barotrauma throw new ArgumentException("Deformable sprites must have one or more subdivisions on each axis."); } + if (!lazyLoad) + { + Init(); + } + + list.Add(this); + } + + public void EnsureLazyLoaded() + { + if (!initialized) { Init(); } + } + + private void Init() + { + if (initialized) { return; } + initialized = true; + foreach (DeformableSprite existing in list) { + if (!existing.initialized || existing == this) { continue; } //share vertex and index buffers if there's already //an existing sprite with the same texture and subdivisions - if (existing.sprite.Texture == sprite.Texture && + if (existing.Sprite.Texture == Sprite.Texture && existing.subDivX == subDivX && existing.subDivY == subDivY && existing.Sprite.SourceRect == Sprite.SourceRect) @@ -83,19 +104,18 @@ namespace Barotrauma } } - if (sprite.Texture != null) + if (Sprite.Texture != null) { SetupVertexBuffers(); SetupIndexBuffer(); } - list.Add(this); } private void SetupVertexBuffers() { - Vector2 textureSize = new Vector2(sprite.Texture.Width, sprite.Texture.Height); - var pos = sprite.SourceRect.Location; - var size = sprite.SourceRect.Size; + Vector2 textureSize = new Vector2(Sprite.Texture.Width, Sprite.Texture.Height); + var pos = Sprite.SourceRect.Location; + var size = Sprite.SourceRect.Size; uvTopLeft = Vector2.Divide(pos.ToVector2(), textureSize); uvBottomRight = Vector2.Divide((pos + size).ToVector2(), textureSize); @@ -119,7 +139,7 @@ namespace Barotrauma uvTopLeft + (uvBottomRight - uvTopLeft) * relativePos; vertices[x + y * (subDivX + 1)] = new VertexPositionColorTexture( - position: new Vector3(relativePos.X * sprite.SourceRect.Width, relativePos.Y * sprite.SourceRect.Height, 0.0f), + position: new Vector3(relativePos.X * Sprite.SourceRect.Width, relativePos.Y * Sprite.SourceRect.Height, 0.0f), color: Color.White, textureCoordinate: uvCoord); } @@ -153,8 +173,8 @@ namespace Barotrauma } } - spritePos = sprite.SourceRect.Location; - spriteSize = sprite.SourceRect.Size; + spritePos = Sprite.SourceRect.Location; + spriteSize = Sprite.SourceRect.Size; } private void SetupIndexBuffer() @@ -195,6 +215,8 @@ namespace Barotrauma /// public void Deform(Func deformFunction) { + if (!initialized) { Init(); } + var deformAmount = new Vector2[subDivX + 1, subDivY + 1]; for (int x = 0; x <= subDivX; x++) { @@ -208,6 +230,8 @@ namespace Barotrauma public void Deform(Vector2[,] deform) { + if (!initialized) { Init(); } + deformArrayWidth = deform.GetLength(0); deformArrayHeight = deform.GetLength(1); if (deformAmount == null || deformAmount.Length != deformArrayWidth * deformArrayHeight) @@ -234,6 +258,8 @@ namespace Barotrauma public Matrix GetTransform(Vector3 pos, Vector2 origin, float rotate, Vector2 scale) { + if (!initialized) { Init(); } + return Matrix.CreateTranslation(-origin.X, -origin.Y, 0) * Matrix.CreateScale(scale.X, -scale.Y, 1.0f) * @@ -243,18 +269,19 @@ namespace Barotrauma public void Draw(Camera cam, Vector3 pos, Vector2 origin, float rotate, Vector2 scale, Color color, bool flip = false) { - if (sprite.Texture == null) { return; } + if (Sprite.Texture == null) { return; } + if (!initialized) { Init(); } // If the source rect is modified, we should recalculate the vertex buffer. - if (sprite.SourceRect.Location != spritePos || sprite.SourceRect.Size != spriteSize) + if (Sprite.SourceRect.Location != spritePos || Sprite.SourceRect.Size != spriteSize) { SetupVertexBuffers(); } #if (LINUX || OSX) - effect.Parameters["TextureSampler+xTexture"].SetValue(sprite.Texture); + effect.Parameters["TextureSampler+xTexture"].SetValue(Sprite.Texture); #else - effect.Parameters["xTexture"].SetValue(sprite.Texture); + effect.Parameters["xTexture"].SetValue(Sprite.Texture); #endif Matrix matrix = GetTransform(pos, origin, rotate, scale); @@ -274,8 +301,8 @@ namespace Barotrauma public void Remove() { - sprite?.Remove(); - sprite = null; + Sprite?.Remove(); + Sprite = null; list.Remove(this); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index eebf1146a..7845f609c 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -26,10 +26,6 @@ namespace Barotrauma.Items.Components private float blinkTimer; - private bool itemLoaded; - - private float blinkTimer; - public PhysicsBody ParentBody; [Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)] diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs index 7246fd680..34d0f2991 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs @@ -337,7 +337,7 @@ namespace Barotrauma SpecularSprite = new Sprite(subElement, lazyLoad: true); break; case "deformablesprite": - DeformableSprite = new DeformableSprite(subElement); + DeformableSprite = new DeformableSprite(subElement, lazyLoad: true); break; case "overridecommonness": string levelType = subElement.GetAttributeString("leveltype", ""); diff --git a/Barotrauma/BarotraumaShared/Source/Sprite/DeformableSprite.cs b/Barotrauma/BarotraumaShared/Source/Sprite/DeformableSprite.cs index aad048132..81ed6f9e8 100644 --- a/Barotrauma/BarotraumaShared/Source/Sprite/DeformableSprite.cs +++ b/Barotrauma/BarotraumaShared/Source/Sprite/DeformableSprite.cs @@ -5,30 +5,25 @@ namespace Barotrauma { partial class DeformableSprite { - private Sprite sprite; - public Vector2 Size { - get { return sprite.size; } + get { return Sprite.size; } } public Vector2 Origin { - get { return sprite.Origin; } - set { sprite.Origin = value; } + get { return Sprite.Origin; } + set { Sprite.Origin = value; } } - public Sprite Sprite + public Sprite Sprite { get; private set; } + + public DeformableSprite(XElement element, int? subdivisionsX = null, int? subdivisionsY = null, string filePath = "", bool lazyLoad = false) { - get { return sprite; } + Sprite = new Sprite(element, file: filePath, lazyLoad: lazyLoad); + InitProjSpecific(element, subdivisionsX, subdivisionsY, lazyLoad); } - public DeformableSprite(XElement element, int? subdivisionsX = null, int? subdivisionsY = null, string filePath = "") - { - sprite = new Sprite(element, file: filePath); - InitProjSpecific(element, subdivisionsX, subdivisionsY); - } - - partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY); + partial void InitProjSpecific(XElement element, int? subdivisionsX, int? subdivisionsY, bool lazyLoad = false); } }