Improved background sprite placement logic: orientation of the cell edges determined by their normals instead of their position relative to the cell
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<backgroundsprites>
|
||||
<hanging1 alignment="Bottom" minsize="0.5" maxsize="1.5" commonness="5">
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation.png" sourcerect="0,0,242,543" origin="0.5,0.0"/>
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation.png" sourcerect="0,0,242,543" origin="0.5,0.15"/>
|
||||
</hanging1>
|
||||
|
||||
<hanging2 alignment="Bottom" minsize="0.5" maxsize="1.5" commonness="5">
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation.png" sourcerect="241,0,322,720" origin="0.5,0.0"/>
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation.png" sourcerect="241,0,322,720" origin="0.5,0.15"/>
|
||||
</hanging2>
|
||||
|
||||
<kelp1 alignment="Top" minsize="0.5" maxsize="1.5" commonness="10">
|
||||
@@ -35,9 +35,14 @@
|
||||
|
||||
<branches2 minsize="0.5" maxsize="2.0" alignwithsurface="true" swingamount="3" randomrotation="-20,20" commonness="4">
|
||||
<overridecommonness commonness="10" leveltype="Maze" />
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="255,0,246,479" origin="0.5,0.9"/>
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="247,0,278,479" origin="0.2,0.9"/>
|
||||
</branches2>
|
||||
|
||||
<branches3 minsize="0.5" maxsize="2.0" alignwithsurface="true" swingamount="3" randomrotation="-20,20" commonness="4">
|
||||
<overridecommonness commonness="10" leveltype="Maze" />
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="526,0,245,479" origin="0.4,0.9"/>
|
||||
</branches3>
|
||||
|
||||
<fungus minsize="0.5" maxsize="1.5" alignwithsurface="true" swingamount="1" commonness="3">
|
||||
<overridecommonness commonness="10" leveltype="Maze" />
|
||||
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="0,681,442,343" origin="0.5,0.9"/>
|
||||
|
||||
@@ -86,36 +86,35 @@ namespace Barotrauma
|
||||
{
|
||||
BackgroundSpritePrefab prefab = GetRandomPrefab(level.GenerationParams.Name);
|
||||
GraphEdge selectedEdge = null;
|
||||
Vector2? pos = FindSpritePosition(level, prefab, out selectedEdge);
|
||||
Vector2 edgeNormal = Vector2.One;
|
||||
Vector2? pos = FindSpritePosition(level, prefab, out selectedEdge, out edgeNormal);
|
||||
|
||||
if (pos == null) continue;
|
||||
|
||||
float rotation = 0.0f;
|
||||
if (prefab.AlignWithSurface)
|
||||
{
|
||||
Vector2 leftPoint = selectedEdge.point2;
|
||||
Vector2 rightPoint = selectedEdge.point1;
|
||||
|
||||
rotation = -MathUtils.VectorToAngle(rightPoint - leftPoint);
|
||||
rotation = MathUtils.VectorToAngle(new Vector2(edgeNormal.Y, edgeNormal.X));
|
||||
}
|
||||
|
||||
rotation += Rand.Range(prefab.RandomRotation.X, prefab.RandomRotation.Y, false);
|
||||
|
||||
var newSprite = new BackgroundSprite(prefab,
|
||||
(Vector2)pos, Rand.Range(prefab.Scale.X, prefab.Scale.Y, false), rotation);
|
||||
|
||||
|
||||
int x = (int)Math.Floor(((Vector2)pos).X / GridSize);
|
||||
if (x<0 || x >= sprites.GetLength(0)) continue;
|
||||
if (x < 0 || x >= sprites.GetLength(0)) continue;
|
||||
int y = (int)Math.Floor(((Vector2)pos).Y / GridSize);
|
||||
if (y<0 || y >= sprites.GetLength(1)) continue;
|
||||
if (y < 0 || y >= sprites.GetLength(1)) continue;
|
||||
|
||||
sprites[x,y].Add(newSprite);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2? FindSpritePosition(Level level, BackgroundSpritePrefab prefab, out GraphEdge closestEdge)
|
||||
private Vector2? FindSpritePosition(Level level, BackgroundSpritePrefab prefab, out GraphEdge closestEdge, out Vector2 edgeNormal)
|
||||
{
|
||||
closestEdge = null;
|
||||
edgeNormal = Vector2.One;
|
||||
|
||||
Vector2 randomPos = new Vector2(
|
||||
Rand.Range(0.0f, level.Size.X, false),
|
||||
@@ -127,43 +126,46 @@ namespace Barotrauma
|
||||
|
||||
VoronoiCell cell = cells[Rand.Int(cells.Count, false)];
|
||||
List<GraphEdge> edges = new List<GraphEdge>();
|
||||
List<Vector2> normals = new List<Vector2>();
|
||||
foreach (GraphEdge edge in cell.edges)
|
||||
{
|
||||
if (!edge.isSolid || edge.OutsideLevel) continue;
|
||||
|
||||
Vector2 normal = edge.GetNormal(cell);
|
||||
|
||||
if (prefab.Alignment.HasFlag(Alignment.Bottom) &&
|
||||
Math.Abs(edge.point1.X - edge.point2.X) < Math.Abs(edge.point1.Y - edge.point2.Y))
|
||||
{
|
||||
if (edge.Center.Y < cell.Center.Y) edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Top) &&
|
||||
Math.Abs(edge.point1.X - edge.point2.X) < Math.Abs(edge.point1.Y - edge.point2.Y))
|
||||
{
|
||||
if (edge.Center.Y > cell.Center.Y) edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Left))
|
||||
{
|
||||
if (edge.Center.X < cell.Center.X) edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Right))
|
||||
{
|
||||
if (edge.Center.X > cell.Center.X) edges.Add(edge);
|
||||
}
|
||||
else
|
||||
if (prefab.Alignment.HasFlag(Alignment.Bottom) && normal.Y < -0.5f)
|
||||
{
|
||||
edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Top) && normal.Y > 0.5f)
|
||||
{
|
||||
edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Left) && normal.X < -0.5f)
|
||||
{
|
||||
edges.Add(edge);
|
||||
}
|
||||
else if (prefab.Alignment.HasFlag(Alignment.Right) && normal.X > 0.5f)
|
||||
{
|
||||
edges.Add(edge);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
normals.Add(normal);
|
||||
}
|
||||
|
||||
if (!edges.Any()) return null;
|
||||
|
||||
closestEdge = edges[Rand.Int(edges.Count,false)];
|
||||
int index = Rand.Int(edges.Count,false);
|
||||
closestEdge = edges[index];
|
||||
edgeNormal = normals[index];
|
||||
|
||||
float length = Vector2.Distance(closestEdge.point1, closestEdge.point2);
|
||||
Vector2 dir = (closestEdge.point1 - closestEdge.point2) / length;
|
||||
Vector2 pos = closestEdge.Center;
|
||||
|
||||
pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f, false);
|
||||
Vector2 pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f, false);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -218,10 +218,25 @@ namespace Voronoi2
|
||||
{
|
||||
return cell1;
|
||||
}
|
||||
else
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the normal of the edge that points outwards from the specified cell
|
||||
/// </summary>
|
||||
public Vector2 GetNormal(VoronoiCell cell)
|
||||
{
|
||||
Vector2 dir = Vector2.Normalize(point1 - point2);
|
||||
|
||||
Vector2 normal = new Vector2(dir.Y, -dir.X);
|
||||
|
||||
if (cell != null && Vector2.Dot(normal, Vector2.Normalize(Center - cell.Center)) < 0)
|
||||
{
|
||||
return null;
|
||||
normal = -normal;
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user