Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -53,6 +53,10 @@ namespace Barotrauma.Lights
[Serialize(0f, IsPropertySaveable.Yes), Editable(MinValueFloat = -360, MaxValueFloat = 360, ValueStep = 1, DecimalCount = 0)]
public float Rotation { get; set; }
[Serialize(false, IsPropertySaveable.Yes, "Directional lights only shine in \"one direction\", meaning no shadows are cast behind them."+
" Note that this does not affect how the light texture is drawn: if you want something like a conical spotlight, you should use an appropriate texture for that.")]
public bool Directional { get; set; }
public Vector2 GetOffset() => Vector2.Transform(Offset, Matrix.CreateRotationZ(MathHelper.ToRadians(Rotation)));
private float flicker;
@@ -206,6 +210,8 @@ namespace Barotrauma.Lights
private readonly List<ConvexHullList> convexHullsInRange;
private readonly HashSet<ConvexHull> visibleConvexHulls = new HashSet<ConvexHull>();
public Texture2D texture;
public SpriteEffects LightSpriteEffect;
@@ -312,6 +318,8 @@ namespace Barotrauma.Lights
if (Math.Abs(value - rotation) < 0.001f) { return; }
rotation = value;
dir = new Vector2(MathF.Cos(rotation), -MathF.Sin(rotation));
if (Math.Abs(rotation - prevCalculatedRotation) < RotationRecalculationThreshold && vertices != null)
{
return;
@@ -322,6 +330,8 @@ namespace Barotrauma.Lights
}
}
private Vector2 dir = Vector2.UnitX;
private Vector2 _spriteScale = Vector2.One;
public Vector2 SpriteScale
@@ -445,7 +455,7 @@ namespace Barotrauma.Lights
public bool Enabled = true;
private readonly ISerializableEntity conditionalTarget;
private readonly PropertyConditional.Comparison comparison;
private readonly PropertyConditional.LogicalOperatorType logicalOperator;
private readonly List<PropertyConditional> conditionals = new List<PropertyConditional>();
public LightSource(ContentXElement element, ISerializableEntity conditionalTarget = null)
@@ -453,11 +463,7 @@ namespace Barotrauma.Lights
{
lightSourceParams = new LightSourceParams(element);
CastShadows = element.GetAttributeBool("castshadows", true);
string comparison = element.GetAttributeString("comparison", null);
if (comparison != null)
{
Enum.TryParse(comparison, ignoreCase: true, out this.comparison);
}
logicalOperator = element.GetAttributeEnum("comparison", logicalOperator);
if (lightSourceParams.DeformableLightSpriteElement != null)
{
@@ -470,13 +476,7 @@ namespace Barotrauma.Lights
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "conditional":
foreach (XAttribute attribute in subElement.Attributes())
{
if (PropertyConditional.IsValid(attribute))
{
conditionals.Add(new PropertyConditional(attribute));
}
}
conditionals.AddRange(PropertyConditional.FromXElement(subElement));
break;
}
}
@@ -539,11 +539,32 @@ namespace Barotrauma.Lights
var fullChList = ConvexHull.HullLists.FirstOrDefault(chList => chList.Submarine == sub);
if (fullChList == null) { return; }
//used to check whether the lightsource hits the target hull if the light is directional
Vector2 ray = new Vector2(dir.X, -dir.Y) * TextureRange;
Vector2 normal = new Vector2(-ray.Y, ray.X);
chList.List.Clear();
foreach (var convexHull in fullChList.List)
{
if (!convexHull.Enabled) { continue; }
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, convexHull.BoundingBox)) { continue; }
if (lightSourceParams.Directional)
{
Rectangle bounds = convexHull.BoundingBox;
//invert because GetLineRectangleIntersection uses the messed up rects that start from top-left
bounds.Y -= bounds.Height;
//the ray can't hit if
// center is in the opposite direction from the ray (cheapest check first)
if (Vector2.Dot(ray, convexHull.BoundingBox.Center.ToVector2() - lightPos) <= 0 &&
/*ray doesn't hit the convex hull*/
!MathUtils.GetLineRectangleIntersection(lightPos, lightPos + ray, bounds, out _) &&
/*normal vectors of the ray don't hit the convex hull */
!MathUtils.GetLineRectangleIntersection(lightPos + normal, lightPos - normal, bounds, out _))
{
continue;
}
}
chList.List.Add(convexHull);
}
chList.IsHidden.RemoveWhere(ch => !chList.List.Contains(ch));
@@ -717,6 +738,8 @@ namespace Barotrauma.Lights
public void RayCastTask(Vector2 drawPos, float rotation)
{
visibleConvexHulls.Clear();
Vector2 drawOffset = Vector2.Zero;
float boundsExtended = TextureRange;
if (OverrideLightTexture != null)
@@ -854,13 +877,15 @@ namespace Barotrauma.Lights
}
}
const float MinPointDistance = 6;
//remove points that are very close to each other
for (int i = 0; i < points.Count; i++)
{
for (int j = Math.Min(i + 4, points.Count - 1); j > i; j--)
{
if (Math.Abs(points[i].WorldPos.X - points[j].WorldPos.X) < 6 &&
Math.Abs(points[i].WorldPos.Y - points[j].WorldPos.Y) < 6)
if (Math.Abs(points[i].WorldPos.X - points[j].WorldPos.X) < MinPointDistance &&
Math.Abs(points[i].WorldPos.Y - points[j].WorldPos.Y) < MinPointDistance)
{
points.RemoveAt(j);
}
@@ -890,7 +915,7 @@ namespace Barotrauma.Lights
foreach (SegmentPoint p in points)
{
Vector2 dir = Vector2.Normalize(p.WorldPos - drawPos);
Vector2 dirNormal = new Vector2(-dir.Y, dir.X) * 3;
Vector2 dirNormal = new Vector2(-dir.Y, dir.X) * MinPointDistance;
//do two slightly offset raycasts to hit the segment itself and whatever's behind it
var intersection1 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 - dirNormal, visibleSegments);
@@ -904,17 +929,12 @@ namespace Barotrauma.Lights
bool isPoint1 = MathUtils.LineToPointDistanceSquared(seg1.Start.WorldPos, seg1.End.WorldPos, p.WorldPos) < 25.0f;
bool isPoint2 = MathUtils.LineToPointDistanceSquared(seg2.Start.WorldPos, seg2.End.WorldPos, p.WorldPos) < 25.0f;
bool markAsVisible = false;
if (isPoint1 && isPoint2)
{
//hit at the current segmentpoint -> place the segmentpoint into the list
verts.Add(p.WorldPos);
foreach (ConvexHullList hullList in convexHullsInRange)
{
hullList.IsHidden.Remove(p.ConvexHull);
hullList.IsHidden.Remove(seg1.ConvexHull);
hullList.IsHidden.Remove(seg2.ConvexHull);
}
markAsVisible = true;
}
else if (intersection1.index != intersection2.index)
{
@@ -922,13 +942,13 @@ namespace Barotrauma.Lights
//we definitely want to generate new geometry here
verts.Add(isPoint1 ? p.WorldPos : intersection1.pos);
verts.Add(isPoint2 ? p.WorldPos : intersection2.pos);
foreach (ConvexHullList hullList in convexHullsInRange)
{
hullList.IsHidden.Remove(p.ConvexHull);
hullList.IsHidden.Remove(seg1.ConvexHull);
hullList.IsHidden.Remove(seg2.ConvexHull);
}
markAsVisible = true;
}
if (markAsVisible)
{
visibleConvexHulls.Add(p.ConvexHull);
visibleConvexHulls.Add(seg1.ConvexHull);
visibleConvexHulls.Add(seg2.ConvexHull);
}
//if neither of the conditions above are met, we just assume
//that the raycasts both resulted on the same segment
@@ -1029,11 +1049,9 @@ namespace Barotrauma.Lights
Vector2 drawPos = calculatedDrawPos;
float cosAngle = (float)Math.Cos(Rotation);
float sinAngle = -(float)Math.Sin(Rotation);
Vector2 uvOffset = Vector2.Zero;
Vector2 overrideTextureDims = Vector2.One;
Vector2 dir = this.dir;
if (OverrideLightTexture != null)
{
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
@@ -1042,8 +1060,7 @@ namespace Barotrauma.Lights
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
{
origin.X = OverrideLightTexture.SourceRect.Width - origin.X;
cosAngle = -cosAngle;
sinAngle = -sinAngle;
dir = -dir;
}
if (LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y; }
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
@@ -1116,8 +1133,8 @@ namespace Barotrauma.Lights
//calculate texture coordinates based on the light's rotation
Vector2 originDiff = diff;
diff.X = originDiff.X * cosAngle - originDiff.Y * sinAngle;
diff.Y = originDiff.X * sinAngle + originDiff.Y * cosAngle;
diff.X = originDiff.X * dir.X - originDiff.Y * dir.Y;
diff.Y = originDiff.X * dir.Y + originDiff.Y * dir.X;
diff *= (overrideTextureDims / OverrideLightTexture.size);// / (1.0f - Math.Max(Math.Abs(uvOffset.X), Math.Abs(uvOffset.Y)));
diff += uvOffset;
}
@@ -1222,9 +1239,6 @@ namespace Barotrauma.Lights
}
drawPos.Y = -drawPos.Y;
float cosAngle = (float)Math.Cos(Rotation);
float sinAngle = -(float)Math.Sin(Rotation);
float bounds = TextureRange;
if (OverrideLightTexture != null)
@@ -1236,8 +1250,8 @@ namespace Barotrauma.Lights
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
origin *= TextureRange;
drawPos.X += origin.X * sinAngle + origin.Y * cosAngle;
drawPos.Y += origin.X * cosAngle + origin.Y * sinAngle;
drawPos.X += origin.X * dir.Y + origin.Y * dir.X;
drawPos.Y += origin.X * dir.X + origin.Y * dir.Y;
}
//add a square-shaped boundary to make sure we've got something to construct the triangles from
@@ -1343,7 +1357,7 @@ namespace Barotrauma.Lights
{
if (conditionals.None()) { return; }
if (conditionalTarget == null) { return; }
if (comparison == PropertyConditional.Comparison.And)
if (logicalOperator == PropertyConditional.LogicalOperatorType.And)
{
Enabled = conditionals.All(c => c.Matches(conditionalTarget));
}
@@ -1396,6 +1410,14 @@ namespace Barotrauma.Lights
return;
}
foreach (var visibleConvexHull in visibleConvexHulls)
{
foreach (var convexHullList in convexHullsInRange)
{
convexHullList.IsHidden.Remove(visibleConvexHull);
}
}
CalculateLightVertices(verts);
LastRecalculationTime = (float)Timing.TotalTime;