(3a5d98b) v0.9.6.0

This commit is contained in:
Regalis
2019-12-17 14:38:24 +01:00
parent 5c95c53118
commit a3569b8bf0
95 changed files with 1579 additions and 728 deletions
@@ -228,12 +228,12 @@ namespace Barotrauma.Lights
activeLights.Clear();
foreach (LightSource light in lights)
{
if (light.Color.A < 1 || light.Range < 1.0f || !light.Enabled) continue;
if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue;
if (!light.Enabled) { continue; }
if ((light.Color.A < 1 || light.Range < 1.0f) && !light.LightSourceParams.OverrideLightSpriteAlpha.HasValue) { continue; }
if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.LightSourceParams.TextureRange, viewRect)) { continue; }
activeLights.Add(light);
}
//clear the lightmap
graphics.Clear(Color.Black);
graphics.BlendState = BlendState.Additive;
@@ -244,9 +244,9 @@ namespace Barotrauma.Lights
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
foreach (LightSource light in activeLights)
{
if (!light.IsBackground) continue;
if (!light.IsBackground) { continue; }
light.DrawSprite(spriteBatch, cam);
light.DrawLightVolume(spriteBatch, lightEffect, transform);
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
backgroundSpritesDrawn = true;
}
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
@@ -288,7 +288,7 @@ namespace Barotrauma.Lights
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
foreach (LightSource light in activeLights)
{
if (light.IsBackground) continue;
if (light.IsBackground) { continue; }
light.DrawSprite(spriteBatch, cam);
}
spriteBatch.End();
@@ -303,6 +303,8 @@ namespace Barotrauma.Lights
//draw characters to obstruct the highlighted items/characters and light sprites
//---------------------------------------------------------------------------------------------------
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
SolidColorEffect.Parameters["color"].SetValue(Color.Black.ToVector4());
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
foreach (Character character in Character.CharacterList)
{
@@ -347,8 +349,8 @@ namespace Barotrauma.Lights
foreach (LightSource light in activeLights)
{
if (light.IsBackground) continue;
light.DrawLightVolume(spriteBatch, lightEffect, transform);
if (light.IsBackground) { continue; }
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
}
Vector3 offset = Vector3.Zero;// new Vector3(Submarine.MainSub.DrawPosition.X, Submarine.MainSub.DrawPosition.Y, 0.0f);
lightEffect.World = Matrix.CreateTranslation(Vector3.Zero) * transform;
@@ -31,10 +31,22 @@ namespace Barotrauma.Lights
get { return range; }
set
{
range = MathHelper.Clamp(value, 0.0f, 2048.0f);
TextureRange = range;
if (OverrideLightTexture != null)
{
TextureRange += Math.Max(
Math.Abs(OverrideLightTexture.RelativeOrigin.X - 0.5f) * OverrideLightTexture.size.X,
Math.Abs(OverrideLightTexture.RelativeOrigin.Y - 0.5f) * OverrideLightTexture.size.Y);
}
}
}
public float TextureRange
{
get;
private set;
}
public Sprite OverrideLightTexture
{
@@ -89,6 +101,8 @@ namespace Barotrauma.Lights
break;
case "lighttexture":
OverrideLightTexture = new Sprite(subElement, preMultiplyAlpha: false);
//refresh TextureRange
Range = range;
break;
}
}
@@ -115,8 +129,16 @@ namespace Barotrauma.Lights
class LightSource
{
//how many pixels the position of the light needs to change for the light volume to be recalculated
const float MovementRecalculationThreshold = 10.0f;
//how many radians the light needs to rotate for the light volume to be recalculated
const float RotationRecalculationThreshold = 0.02f;
private static Texture2D lightTexture;
private VertexPositionColorTexture[] vertices;
private short[] indices;
private List<ConvexHullList> hullsInRange;
public Texture2D texture;
@@ -167,6 +189,9 @@ namespace Barotrauma.Lights
private int vertexCount;
private int indexCount;
private Vector2 translateVertices;
private float rotateVertices;
private readonly LightSourceParams lightSourceParams;
public LightSourceParams LightSourceParams => lightSourceParams;
@@ -177,26 +202,38 @@ namespace Barotrauma.Lights
get { return position; }
set
{
if (Math.Abs(position.X - value.X) < 0.1f && Math.Abs(position.Y - value.Y) < 0.1f) return;
Vector2 moveAmount = value - position;
if (Math.Abs(moveAmount.X) < 0.1f && Math.Abs(moveAmount.Y) < 0.1f) { return; }
position = value;
if (Vector2.DistanceSquared(prevCalculatedPosition, position) < 5.0f * 5.0f) return;
//translate light volume manually instead of doing a full recalculation when moving by a small amount
if (Vector2.DistanceSquared(prevCalculatedPosition, position) < MovementRecalculationThreshold * MovementRecalculationThreshold && vertices != null)
{
translateVertices = position - prevCalculatedPosition;
return;
}
NeedsHullCheck = true;
NeedsRecalculation = true;
prevCalculatedPosition = position;
}
}
private float prevCalculatedRotation;
private float rotation;
public float Rotation
{
get { return rotation; }
set
{
if (Math.Abs(rotation - value) < 0.01f) return;
if (Math.Abs(value - rotation) < 0.001f) { return; }
rotation = value;
if (Math.Abs(rotation - prevCalculatedRotation) < RotationRecalculationThreshold && vertices != null)
{
rotateVertices = rotation - prevCalculatedRotation;
return;
}
NeedsHullCheck = true;
NeedsRecalculation = true;
}
@@ -711,16 +748,25 @@ namespace Barotrauma.Lights
return retVal;
}
private void CalculateLightVertices(List<Vector2> rayCastHits)
{
List<VertexPositionColorTexture> vertices = new List<VertexPositionColorTexture>();
vertexCount = rayCastHits.Count * 2 + 1;
indexCount = (rayCastHits.Count) * 9;
//recreate arrays if they're too small or excessively large
if (vertices == null || vertices.Length < vertexCount || vertices.Length > vertexCount * 3)
{
vertices = new VertexPositionColorTexture[vertexCount];
indices = new short[indexCount];
}
Vector2 drawPos = position;
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
if (ParentSub != null) { drawPos += ParentSub.DrawPosition; }
float cosAngle = (float)Math.Cos(Rotation);
float sinAngle = -(float)Math.Sin(Rotation);
Vector2 uvOffset = Vector2.Zero;
Vector2 overrideTextureDims = Vector2.One;
if (OverrideLightTexture != null)
@@ -728,15 +774,15 @@ namespace Barotrauma.Lights
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
Vector2 origin = OverrideLightTexture.Origin;
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) origin.X = OverrideLightTexture.SourceRect.Width - origin.X;
if (LightSpriteEffect == SpriteEffects.FlipVertically) origin.Y = (OverrideLightTexture.SourceRect.Height - origin.Y);
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = OverrideLightTexture.SourceRect.Width - origin.X; }
if (LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y; }
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
}
// Add a vertex for the center of the mesh
vertices.Add(new VertexPositionColorTexture(new Vector3(position.X, position.Y, 0),
Color.White, new Vector2(0.5f, 0.5f) + uvOffset));
vertices[0] = new VertexPositionColorTexture(new Vector3(position.X, position.Y, 0),
Color.White, GetUV(new Vector2(0.5f, 0.5f) + uvOffset, LightSpriteEffect));
//hacky fix to exc excessively large light volumes (they used to be up to 4x the range of the light if there was nothing to block the rays).
//might want to tweak the raycast logic in a way that this isn't necessary
float boundRadius = Range * 1.1f / (1.0f - Math.Max(Math.Abs(uvOffset.X), Math.Abs(uvOffset.Y)));
@@ -800,68 +846,88 @@ namespace Barotrauma.Lights
//finally, create the vertices
VertexPositionColorTexture fullVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X, position.Y + rawDiff.Y, 0),
Color.White, new Vector2(0.5f, 0.5f) + diff);
Color.White, GetUV(new Vector2(0.5f, 0.5f) + diff, LightSpriteEffect));
VertexPositionColorTexture fadeVert = new VertexPositionColorTexture(new Vector3(position.X + rawDiff.X + nDiff.X, position.Y + rawDiff.Y + nDiff.Y, 0),
Color.White * 0.0f, new Vector2(0.5f, 0.5f) + diff);
Color.White * 0.0f, GetUV(new Vector2(0.5f, 0.5f) + diff, LightSpriteEffect));
vertices.Add(fullVert);
vertices.Add(fadeVert);
vertices[1 + i * 2] = fullVert;
vertices[1 + i * 2 + 1] = fadeVert;
}
// Compute the indices to form triangles
List<short> indices = new List<short>();
for (int i = 0; i < rayCastHits.Count-1; i++)
for (int i = 0; i < rayCastHits.Count - 1; i++)
{
//main light body
indices.Add(0);
indices.Add((short)((i*2 + 3) % vertices.Count));
indices.Add((short)((i*2 + 1) % vertices.Count));
indices[i * 9] = 0;
indices[i * 9 + 1] = (short)((i * 2 + 3) % vertexCount);
indices[i * 9 + 2] = (short)((i * 2 + 1) % vertexCount);
//faded light
indices.Add((short)((i*2 + 1) % vertices.Count));
indices.Add((short)((i*2 + 3) % vertices.Count));
indices.Add((short)((i*2 + 4) % vertices.Count));
indices[i * 9 + 3] = (short)((i * 2 + 1) % vertexCount);
indices[i * 9 + 4] = (short)((i * 2 + 3) % vertexCount);
indices[i * 9 + 5] = (short)((i * 2 + 4) % vertexCount);
indices.Add((short)((i*2 + 2) % vertices.Count));
indices.Add((short)((i*2 + 1) % vertices.Count));
indices.Add((short)((i*2 + 4) % vertices.Count));
indices[i * 9 + 6] = (short)((i * 2 + 2) % vertexCount);
indices[i * 9 + 7] = (short)((i * 2 + 1) % vertexCount);
indices[i * 9 + 8] = (short)((i * 2 + 4) % vertexCount);
}
//main light body
indices.Add(0);
indices.Add((short)(1));
indices.Add((short)(vertices.Count - 2));
indices[(rayCastHits.Count - 1) * 9] = 0;
indices[(rayCastHits.Count - 1) * 9 + 1] = (short)(1);
indices[(rayCastHits.Count - 1) * 9 + 2] = (short)(vertexCount - 2);
//faded light
indices.Add((short)(1));
indices.Add((short)(vertices.Count-1));
indices.Add((short)(vertices.Count-2));
indices[(rayCastHits.Count - 1) * 9 + 3] = (short)(1);
indices[(rayCastHits.Count - 1) * 9 + 4] = (short)(vertexCount - 1);
indices[(rayCastHits.Count - 1) * 9 + 5] = (short)(vertexCount - 2);
indices.Add((short)(1));
indices.Add((short)(2));
indices.Add((short)(vertices.Count-1));
vertexCount = vertices.Count;
indexCount = indices.Count;
indices[(rayCastHits.Count - 1) * 9 + 6] = (short)(1);
indices[(rayCastHits.Count - 1) * 9 + 7] = (short)(2);
indices[(rayCastHits.Count - 1) * 9 + 8] = (short)(vertexCount - 1);
//TODO: a better way to determine the size of the vertex buffer and handle changes in size?
//now we just create a buffer for 64 verts and make it larger if needed
if (lightVolumeBuffer == null)
{
lightVolumeBuffer = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, Math.Max(64, (int)(vertexCount*1.5)), BufferUsage.None);
lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), Math.Max(64*3, (int)(indexCount * 1.5)), BufferUsage.None);
lightVolumeBuffer = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, Math.Max(64, (int)(vertexCount * 1.5)), BufferUsage.None);
lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), Math.Max(64 * 3, (int)(indexCount * 1.5)), BufferUsage.None);
}
else if (vertexCount > lightVolumeBuffer.VertexCount || indexCount > lightVolumeIndexBuffer.IndexCount)
{
lightVolumeBuffer.Dispose();
lightVolumeIndexBuffer.Dispose();
lightVolumeBuffer = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, (int)(vertexCount*1.5), BufferUsage.None);
lightVolumeBuffer = new DynamicVertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, (int)(vertexCount * 1.5), BufferUsage.None);
lightVolumeIndexBuffer = new DynamicIndexBuffer(GameMain.Instance.GraphicsDevice, typeof(short), (int)(indexCount * 1.5), BufferUsage.None);
}
lightVolumeBuffer.SetData<VertexPositionColorTexture>(vertices.ToArray());
lightVolumeIndexBuffer.SetData<short>(indices.ToArray());
lightVolumeBuffer.SetData<VertexPositionColorTexture>(vertices, 0, vertexCount);
lightVolumeIndexBuffer.SetData<short>(indices, 0, indexCount);
Vector2 GetUV(Vector2 vert, SpriteEffects effects)
{
if (effects == SpriteEffects.FlipHorizontally)
{
vert.X = 1.0f - vert.X;
}
else if (effects == SpriteEffects.FlipVertically)
{
vert.Y = 1.0f - vert.Y;
}
else if (effects == (SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically))
{
vert.X = 1.0f - vert.X;
vert.Y = 1.0f - vert.Y;
}
vert.Y = 1.0f - vert.Y;
return vert;
}
translateVertices = Vector2.Zero;
rotateVertices = 0.0f;
prevCalculatedPosition = position;
prevCalculatedRotation = rotation;
}
/// <summary>
@@ -944,15 +1010,12 @@ namespace Barotrauma.Lights
Vector2 drawPos = position;
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
drawPos.Y = -drawPos.Y;
drawPos.Y = -drawPos.Y;
spriteBatch.Draw(currentTexture, drawPos, null, Color, -rotation, center, scale, SpriteEffects.None, 1);
return;
}
Vector3 offset = ParentSub == null ?
Vector3.Zero : new Vector3(ParentSub.DrawPosition.X, ParentSub.DrawPosition.Y, 0.0f);
lightEffect.World = Matrix.CreateTranslation(offset) * transform;
if (NeedsRecalculation)
{
@@ -962,8 +1025,16 @@ namespace Barotrauma.Lights
lastRecalculationTime = (float)Timing.TotalTime;
NeedsRecalculation = false;
}
if (vertexCount == 0) return;
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
lightEffect.World =
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
Matrix.CreateRotationZ(rotateVertices) *
Matrix.CreateTranslation(new Vector3(position + offset + translateVertices, 0.0f)) *
transform;
if (vertexCount == 0) { return; }
lightEffect.DiffuseColor = (new Vector3(Color.R, Color.G, Color.B) * (Color.A / 255.0f)) / 255.0f;
if (OverrideLightTexture != null)