Unstable 1.1.14.0
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user