(3a5d98b) v0.9.6.0
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user