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" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<backgroundsprites>
|
<backgroundsprites>
|
||||||
<hanging1 alignment="Bottom" minsize="0.5" maxsize="1.5" commonness="5">
|
<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>
|
</hanging1>
|
||||||
|
|
||||||
<hanging2 alignment="Bottom" minsize="0.5" maxsize="1.5" commonness="5">
|
<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>
|
</hanging2>
|
||||||
|
|
||||||
<kelp1 alignment="Top" minsize="0.5" maxsize="1.5" commonness="10">
|
<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">
|
<branches2 minsize="0.5" maxsize="2.0" alignwithsurface="true" swingamount="3" randomrotation="-20,20" commonness="4">
|
||||||
<overridecommonness commonness="10" leveltype="Maze" />
|
<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>
|
</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">
|
<fungus minsize="0.5" maxsize="1.5" alignwithsurface="true" swingamount="1" commonness="3">
|
||||||
<overridecommonness commonness="10" leveltype="Maze" />
|
<overridecommonness commonness="10" leveltype="Maze" />
|
||||||
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="0,681,442,343" origin="0.5,0.9"/>
|
<Sprite texture="Content/BackgroundSprites/vegetation2.png" sourcerect="0,681,442,343" origin="0.5,0.9"/>
|
||||||
|
|||||||
@@ -86,17 +86,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
BackgroundSpritePrefab prefab = GetRandomPrefab(level.GenerationParams.Name);
|
BackgroundSpritePrefab prefab = GetRandomPrefab(level.GenerationParams.Name);
|
||||||
GraphEdge selectedEdge = null;
|
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;
|
if (pos == null) continue;
|
||||||
|
|
||||||
float rotation = 0.0f;
|
float rotation = 0.0f;
|
||||||
if (prefab.AlignWithSurface)
|
if (prefab.AlignWithSurface)
|
||||||
{
|
{
|
||||||
Vector2 leftPoint = selectedEdge.point2;
|
rotation = MathUtils.VectorToAngle(new Vector2(edgeNormal.Y, edgeNormal.X));
|
||||||
Vector2 rightPoint = selectedEdge.point1;
|
|
||||||
|
|
||||||
rotation = -MathUtils.VectorToAngle(rightPoint - leftPoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rotation += Rand.Range(prefab.RandomRotation.X, prefab.RandomRotation.Y, false);
|
rotation += Rand.Range(prefab.RandomRotation.X, prefab.RandomRotation.Y, false);
|
||||||
@@ -105,17 +103,18 @@ namespace Barotrauma
|
|||||||
(Vector2)pos, Rand.Range(prefab.Scale.X, prefab.Scale.Y, false), rotation);
|
(Vector2)pos, Rand.Range(prefab.Scale.X, prefab.Scale.Y, false), rotation);
|
||||||
|
|
||||||
int x = (int)Math.Floor(((Vector2)pos).X / GridSize);
|
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);
|
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);
|
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;
|
closestEdge = null;
|
||||||
|
edgeNormal = Vector2.One;
|
||||||
|
|
||||||
Vector2 randomPos = new Vector2(
|
Vector2 randomPos = new Vector2(
|
||||||
Rand.Range(0.0f, level.Size.X, false),
|
Rand.Range(0.0f, level.Size.X, false),
|
||||||
@@ -127,43 +126,46 @@ namespace Barotrauma
|
|||||||
|
|
||||||
VoronoiCell cell = cells[Rand.Int(cells.Count, false)];
|
VoronoiCell cell = cells[Rand.Int(cells.Count, false)];
|
||||||
List<GraphEdge> edges = new List<GraphEdge>();
|
List<GraphEdge> edges = new List<GraphEdge>();
|
||||||
|
List<Vector2> normals = new List<Vector2>();
|
||||||
foreach (GraphEdge edge in cell.edges)
|
foreach (GraphEdge edge in cell.edges)
|
||||||
{
|
{
|
||||||
if (!edge.isSolid || edge.OutsideLevel) continue;
|
if (!edge.isSolid || edge.OutsideLevel) continue;
|
||||||
|
|
||||||
if (prefab.Alignment.HasFlag(Alignment.Bottom) &&
|
Vector2 normal = edge.GetNormal(cell);
|
||||||
Math.Abs(edge.point1.X - edge.point2.X) < Math.Abs(edge.point1.Y - edge.point2.Y))
|
|
||||||
{
|
if (prefab.Alignment.HasFlag(Alignment.Bottom) && normal.Y < -0.5f)
|
||||||
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
|
|
||||||
{
|
{
|
||||||
edges.Add(edge);
|
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;
|
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);
|
float length = Vector2.Distance(closestEdge.point1, closestEdge.point2);
|
||||||
Vector2 dir = (closestEdge.point1 - closestEdge.point2) / length;
|
Vector2 dir = (closestEdge.point1 - closestEdge.point2) / length;
|
||||||
Vector2 pos = closestEdge.Center;
|
Vector2 pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f, false);
|
||||||
|
|
||||||
pos = closestEdge.point2 + dir * Rand.Range(prefab.Sprite.size.X / 2.0f, length - prefab.Sprite.size.X / 2.0f, false);
|
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,10 +218,25 @@ namespace Voronoi2
|
|||||||
{
|
{
|
||||||
return cell1;
|
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