(50a891840) Lazy deformable LevelObject sprite loading

This commit is contained in:
Joonas Rikkonen
2019-04-03 16:25:31 +03:00
parent 8bf3927d98
commit 1f94e174ef
7 changed files with 59 additions and 38 deletions

View File

@@ -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")
{

View File

@@ -78,6 +78,7 @@ namespace Barotrauma
{
Prefab.Sprite?.EnsureLazyLoaded();
Prefab.SpecularSprite?.EnsureLazyLoaded();
Prefab.DeformableSprite?.EnsureLazyLoaded();
CurrentSwingAmount = Prefab.SwingAmountRad;
CurrentScaleOscillation = Prefab.ScaleOscillation;

View File

@@ -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();

View File

@@ -12,6 +12,8 @@ namespace Barotrauma
{
private static List<DeformableSprite> list = new List<DeformableSprite>();
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
/// </summary>
public void Deform(Func<Vector2, Vector2> 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);

View File

@@ -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)]

View File

@@ -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", "");

View File

@@ -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);
}
}