Browse Source

New Planet Placement

master
laurids 3 years ago
parent
commit
c340e6839d
4 changed files with 1004 additions and 75 deletions
  1. +833
    -58
      Assets/GWConquest/Scenes/GalaxyMap.unity
  2. +1
    -0
      Assets/GWConquest/Scripts/Planet.cs
  3. +129
    -17
      Assets/GWConquest/Scripts/PlanetPlacement.cs
  4. +41
    -0
      Assets/GWConquest/Scripts/Util.cs

+ 833
- 58
Assets/GWConquest/Scenes/GalaxyMap.unity
File diff suppressed because it is too large
View File


+ 1
- 0
Assets/GWConquest/Scripts/Planet.cs View File

@ -52,6 +52,7 @@ namespace GWConquest
public Transform planetCameraTransform;
public GameObject AdditionalObjects;
public bool RefuseConnections = false;
public PlanetData PlanetData
{


+ 129
- 17
Assets/GWConquest/Scripts/PlanetPlacement.cs View File

@ -47,6 +47,15 @@ namespace GWConquest
public float Pass2AdditionalConnectionChance;
public float Pass2MaxAdditionalConnectionDistance;
public Vector2 Pass2New_GalaxyRadius;
public int Pass2New_MinPlanets;
public int Pass2New_MaxPlanets;
public float Pass2New_MinPlanetDistance;
public float Pass2New_MinPlanetToLineDistance;
public float Pass2New_MaxConnectionDistance;
public int Pass2New_MinConnections;
public int Pass2New_MaxConnections;
public List<string> AvailableNames = new List<string>();
private string DrawName()
@ -62,7 +71,7 @@ namespace GWConquest
return name;
}
public Planet PlacePlanet(Vector3 position)
public Planet PlacePlanet(Vector3 position, ref int nextZoneId)
{
var planetGO = BoltNetwork.Instantiate(BoltPrefabs.Planet, position, Quaternion.identity);
@ -79,6 +88,12 @@ namespace GWConquest
InitPlanetPrefab(planet);
foreach(Zone z in planet.GetComponentsInChildren<Zone>())
{
z.SetZoneId(nextZoneId);
nextZoneId++;
}
return planet;
}
@ -165,13 +180,7 @@ namespace GWConquest
pos += new Vector3(randomOffset.x, 0f, randomOffset.y);
var planet = PlacePlanet(pos);
foreach(Zone z in planet.GetComponentsInChildren<Zone>())
{
z.SetZoneId(nextZoneId);
nextZoneId++;
}
var planet = PlacePlanet(pos, ref nextZoneId);
spawnedConnections.Add(SpawnPlanetConnection(prevPlanet, planet));
@ -186,6 +195,14 @@ namespace GWConquest
}
// second pass
PlacePlanetsSecondPassNew(allPlanets, spawnedConnections, ref nextZoneId);
int finalPlanetCount = allPlanets.Count;
BoltLog.Info("Additional planets: {0}", finalPlanetCount-origPlanetCount);
}
private void PlacePlanetsSecondPass(List<Planet> allPlanets, List<PlanetConnection> spawnedConnections, ref int nextZoneId)
{
foreach(var conn in spawnedConnections)
{
if(Random.value <= Pass2PlanetChance)
@ -203,13 +220,7 @@ namespace GWConquest
float transverseDistance = Random.Range(Pass2MinDistance, Pass2MaxDistance);
Vector3 pos = start + transverseDistance * transverse;
var planet = PlacePlanet(pos);
foreach(Zone z in planet.GetComponentsInChildren<Zone>())
{
z.SetZoneId(nextZoneId);
nextZoneId++;
}
var planet = PlacePlanet(pos, ref nextZoneId);
bool twoConnections = Random.value <= Pass2SecondConnectionChance;
bool firstConnected = Random.value <= 0.5f;
@ -236,10 +247,111 @@ namespace GWConquest
allPlanets.Add(planet);
}
}
}
int finalPlanetCount = allPlanets.Count;
BoltLog.Info("Additional planets: {0}", finalPlanetCount-origPlanetCount);
private void PlacePlanetsSecondPassNew(List<Planet> allPlanets, List<PlanetConnection> spawnedConnections, ref int nextZoneId)
{
int planetsToSpawn = Random.Range(Pass2New_MinPlanets, Pass2New_MaxPlanets);
BoltLog.Info("Spawning {0} planets in second pass.", planetsToSpawn);
Vector3 galaxyCenter = transform.position;
List<Vector3> planetPositions = allPlanets.Select(p => p.transform.position).ToList();
var allConnections = FindObjectsOfType<PlanetConnection>().ToList();
float minDistSq = Mathf.Pow(Pass2New_MinPlanetDistance, 2f);
float minLineDistSq = Mathf.Pow(Pass2New_MinPlanetToLineDistance, 2f);
float maxDistSq = Mathf.Pow(Pass2New_MaxConnectionDistance, 2f);
int maxTries = 1000;
for(int i = 0; i < planetsToSpawn; i++)
{
bool hasSpawned = false;
for(int j = 0; j < maxTries; j++)
{
Vector2 randomPoint = Random.insideUnitCircle * Pass2New_GalaxyRadius;
Vector3 point = new Vector3(randomPoint.x, 0, randomPoint.y) + galaxyCenter;
bool pointValid = true;
foreach(Vector3 planetPos in planetPositions)
{
float distSq = Vector3.SqrMagnitude(point - planetPos);
if(distSq < minDistSq)
{
pointValid = false;
break;
}
}
if(pointValid)
{
foreach(var conn in allConnections)
{
float distSq = Util.DistanceToLineSegmentSqr(conn.planet1.transform.position, conn.planet2.transform.position, point);
if(distSq < minLineDistSq)
{
pointValid = false;
break;
}
}
}
if(pointValid)
{
planetPositions.Add(point);
var planet = PlacePlanet(point, ref nextZoneId);
// connections here
var closePlanets = allPlanets.Where(p => !p.RefuseConnections && Vector3.SqrMagnitude(p.transform.position - point) <= maxDistSq).OrderBy(p => Random.value);
int connCount = Random.Range(Pass2New_MinConnections, Pass2New_MaxConnections);
connCount = Mathf.Min(connCount, closePlanets.Count());
int spawnedCount = 0;
foreach(Planet p in closePlanets)
{
// check if connection intersects with other connection in range
bool intersects = false;
foreach(PlanetConnection otherConn in allConnections)
{
if(Util.DoLinesIntersect(point, p.transform.position, otherConn.planet1.transform.position, otherConn.planet2.transform.position))
{
intersects = true;
break;
}
}
if(!intersects)
{
var newConn = SpawnPlanetConnection(planet, p);
allConnections.Add(newConn);
spawnedCount++;
}
if(spawnedCount >= connCount)
{
break;
}
}
planet.InitNonStatic();
allPlanets.Add(planet);
hasSpawned = true;
break;
}
}
if(!hasSpawned)
{
BoltLog.Warn("Could not find a position to place the {0}th planet. Aborting.", i);
break;
}
}
}
}
}

+ 41
- 0
Assets/GWConquest/Scripts/Util.cs View File

@ -257,6 +257,47 @@ namespace GWConquest
return new Color(r,g,b,a);
}
public static bool DoLinesIntersect(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float epsilon = 0.01f)
{
float det = (a.x-b.x) * (c.z-d.z) - (a.z-b.z) * (c.x-d.x);
if(Mathf.Abs(det) <= Mathf.Epsilon)
{
//Debug.LogFormat("lines are almost parallel!");
return false;
}
float t = ((a.x-b.x) * (c.z-a.z) - (a.z-b.z) * (c.x-a.x)) / det;
float s = ((c.x-d.x) * (c.z-a.z) - (c.z-d.z) * (c.x-a.x)) / det;
bool intersects = epsilon <= s && s <= 1f - epsilon && epsilon <= t && t <= 1f - epsilon;
//Debug.LogFormat("lines: det = {0}; s = {1}; t = {2}; intersects = {3}", det, s, t, intersects);
return intersects;
}
public static float DistanceToLineSegmentSqr(Vector3 a, Vector3 b, Vector3 p)
{
Vector3 diff = b - a;
float s = Vector3.Dot(p-a, diff) / diff.sqrMagnitude;
if(s < 0f)
{
// compare to a
return Vector3.SqrMagnitude(a-p);
}
else if(s > 1f)
{
// compare to b
return Vector3.SqrMagnitude(b-p);
}
else{
// compare to line
Vector3 x = a + s * diff;
return Vector3.SqrMagnitude(x-p);
}
}
}
}

Loading…
Cancel
Save