feat: improved visualisation and x4 data import
This commit is contained in:
@@ -8,19 +8,11 @@ public sealed partial class ScenarioLoader
|
||||
private const string DevelopmentCompanionSystemId = "helios";
|
||||
|
||||
private static List<SolarSystemDefinition> InjectSpecialSystems(
|
||||
IReadOnlyList<SolarSystemDefinition> authoredSystems,
|
||||
bool includeSolSystem)
|
||||
IReadOnlyList<SolarSystemDefinition> authoredSystems)
|
||||
{
|
||||
var systems = authoredSystems
|
||||
return authoredSystems
|
||||
.Select(CloneSystemDefinition)
|
||||
.ToList();
|
||||
|
||||
if (includeSolSystem && systems.All((system) => system.Id != "sol"))
|
||||
{
|
||||
systems.Add(CreateSolSystem());
|
||||
}
|
||||
|
||||
return systems;
|
||||
}
|
||||
|
||||
private static List<SolarSystemDefinition> ExpandSystems(
|
||||
@@ -156,12 +148,16 @@ public sealed partial class ScenarioLoader
|
||||
Id = id,
|
||||
Label = label,
|
||||
Position = [position.X, position.Y, position.Z],
|
||||
StarKind = starProfile.Kind,
|
||||
StarCount = starProfile.StarCount,
|
||||
StarColor = starProfile.StarColor,
|
||||
StarGlow = starProfile.StarGlow,
|
||||
StarSize = starProfile.BaseSize + ((generatedIndex % 4) * 2f),
|
||||
GravityWellRadius = template.GravityWellRadius + ((generatedIndex % 3) * 12f),
|
||||
Stars =
|
||||
[
|
||||
new StarDefinition
|
||||
{
|
||||
Kind = starProfile.Kind,
|
||||
Color = starProfile.StarColor,
|
||||
Glow = starProfile.StarGlow,
|
||||
Size = starProfile.BaseSize + ((generatedIndex % 4) * 2f),
|
||||
},
|
||||
],
|
||||
AsteroidField = new AsteroidFieldDefinition
|
||||
{
|
||||
DecorationCount = template.AsteroidField.DecorationCount + ((generatedIndex % 5) * 10),
|
||||
@@ -181,12 +177,7 @@ public sealed partial class ScenarioLoader
|
||||
Id = definition.Id,
|
||||
Label = definition.Label,
|
||||
Position = definition.Position.ToArray(),
|
||||
StarKind = definition.StarKind,
|
||||
StarCount = definition.StarCount,
|
||||
StarColor = definition.StarColor,
|
||||
StarGlow = definition.StarGlow,
|
||||
StarSize = definition.StarSize,
|
||||
GravityWellRadius = definition.GravityWellRadius,
|
||||
Stars = definition.Stars.Select(s => new StarDefinition { Kind = s.Kind, Color = s.Color, Glow = s.Glow, Size = s.Size, OrbitRadius = s.OrbitRadius, OrbitSpeed = s.OrbitSpeed, OrbitPhaseAtEpoch = s.OrbitPhaseAtEpoch }).ToList(),
|
||||
AsteroidField = new AsteroidFieldDefinition
|
||||
{
|
||||
DecorationCount = definition.AsteroidField.DecorationCount,
|
||||
@@ -214,7 +205,7 @@ public sealed partial class ScenarioLoader
|
||||
Label = planet.Label,
|
||||
PlanetType = planet.PlanetType,
|
||||
Shape = planet.Shape,
|
||||
MoonCount = planet.MoonCount,
|
||||
Moons = planet.Moons.Select(m => new MoonDefinition { Label = m.Label, Size = m.Size, Color = m.Color, OrbitRadius = m.OrbitRadius, OrbitSpeed = m.OrbitSpeed, OrbitPhaseAtEpoch = m.OrbitPhaseAtEpoch, OrbitInclination = m.OrbitInclination, OrbitLongitudeOfAscendingNode = m.OrbitLongitudeOfAscendingNode }).ToList(),
|
||||
OrbitRadius = planet.OrbitRadius,
|
||||
OrbitSpeed = planet.OrbitSpeed,
|
||||
OrbitEccentricity = planet.OrbitEccentricity,
|
||||
@@ -387,14 +378,15 @@ public sealed partial class ScenarioLoader
|
||||
orbitRadius += profile.OrbitGapMin + (Hash01(generatedIndex, 10 + index) * (profile.OrbitGapMax - profile.OrbitGapMin));
|
||||
var orbitEccentricity = 0.01f + (Hash01(generatedIndex, 20 + index) * 0.16f);
|
||||
var orbitInclination = -9f + (Hash01(generatedIndex, 30 + index) * 18f);
|
||||
var moonVariance = (int)MathF.Floor(Hash01(generatedIndex, 40 + index) * 3f);
|
||||
var moonCount = profile.BaseMoonCount + (int)MathF.Floor(Hash01(generatedIndex, 40 + index) * 3f);
|
||||
var planetLabel = $"{BuildPlanetBaseName(generatedIndex, index)}-{index + 1}";
|
||||
|
||||
planets.Add(new PlanetDefinition
|
||||
{
|
||||
Label = $"{BuildPlanetBaseName(generatedIndex, index)}-{index + 1}",
|
||||
Label = planetLabel,
|
||||
PlanetType = profile.Type,
|
||||
Shape = profile.Shape,
|
||||
MoonCount = profile.BaseMoonCount + moonVariance,
|
||||
Moons = GenerateMoons(planetLabel, profile.BaseSize, moonCount),
|
||||
OrbitRadius = orbitRadius,
|
||||
OrbitSpeed = 0.11f / MathF.Sqrt(MathF.Max(orbitRadius * orbitRadius * orbitRadius, 0.02f)),
|
||||
OrbitEccentricity = orbitEccentricity,
|
||||
@@ -471,12 +463,44 @@ public sealed partial class ScenarioLoader
|
||||
return (value & 0x00ffffff) / 16777215f;
|
||||
}
|
||||
|
||||
private static List<MoonDefinition> GenerateMoons(string planetLabel, float planetSize, int moonCount)
|
||||
{
|
||||
var seed = planetLabel.Aggregate(0, (acc, c) => acc * 31 + c);
|
||||
var moons = new List<MoonDefinition>(moonCount);
|
||||
for (var moonIndex = 0; moonIndex < moonCount; moonIndex += 1)
|
||||
{
|
||||
var spacing = planetSize * 1.4f;
|
||||
var radiusVariance = Hash01(seed, 10 + moonIndex) * planetSize * 0.9f;
|
||||
var orbitRadius = (planetSize * 1.8f) + (moonIndex * spacing) + radiusVariance;
|
||||
var orbitSpeed = 0.9f / MathF.Sqrt(MathF.Max(orbitRadius, 1f)) + (moonIndex * 0.003f);
|
||||
var phase = Hash01(seed, 20 + moonIndex) * 360f;
|
||||
var inclination = (Hash01(seed, 30 + moonIndex) - 0.5f) * 28f;
|
||||
var ascendingNode = Hash01(seed, 40 + moonIndex) * 360f;
|
||||
var sizeBase = MathF.Max(2.2f, planetSize * 0.11f);
|
||||
var sizeVariance = Hash01(seed, 50 + moonIndex) * MathF.Max(planetSize * 0.16f, 2.5f);
|
||||
var size = MathF.Min(sizeBase + sizeVariance, planetSize * 0.42f);
|
||||
|
||||
moons.Add(new MoonDefinition
|
||||
{
|
||||
Label = $"{planetLabel}-m{moonIndex + 1}",
|
||||
Size = size,
|
||||
Color = "#c8c4bc",
|
||||
OrbitRadius = orbitRadius,
|
||||
OrbitSpeed = orbitSpeed,
|
||||
OrbitPhaseAtEpoch = phase,
|
||||
OrbitInclination = inclination,
|
||||
OrbitLongitudeOfAscendingNode = ascendingNode,
|
||||
});
|
||||
}
|
||||
|
||||
return moons;
|
||||
}
|
||||
|
||||
private sealed record StarProfile(
|
||||
string Kind,
|
||||
string StarColor,
|
||||
string StarGlow,
|
||||
float BaseSize,
|
||||
int StarCount);
|
||||
float BaseSize);
|
||||
|
||||
private sealed record PlanetProfile(
|
||||
string Type,
|
||||
@@ -490,106 +514,4 @@ public sealed partial class ScenarioLoader
|
||||
public float OrbitGapMax => OrbitGapMin + MathF.Max(0.12f, OrbitGapMin * 0.45f);
|
||||
}
|
||||
|
||||
private static SolarSystemDefinition CreateSolSystem()
|
||||
{
|
||||
var mercuryOrbitAu = 0.3871f;
|
||||
var venusOrbitAu = 0.7233f;
|
||||
var earthOrbitAu = 1.000f;
|
||||
var marsOrbitAu = 1.5237f;
|
||||
var jupiterOrbitAu = 5.203f;
|
||||
var saturnOrbitAu = 9.582f;
|
||||
var uranusOrbitAu = 19.201f;
|
||||
var neptuneOrbitAu = 30.047f;
|
||||
|
||||
return new SolarSystemDefinition
|
||||
{
|
||||
Id = "sol",
|
||||
Label = "Sol",
|
||||
Position = [18.2f, 0.02f, -11.8f],
|
||||
StarKind = "main-sequence",
|
||||
StarCount = 1,
|
||||
StarColor = "#fff1b8",
|
||||
StarGlow = "#ffd35a",
|
||||
StarSize = 696340f,
|
||||
GravityWellRadius = 240f,
|
||||
AsteroidField = new AsteroidFieldDefinition
|
||||
{
|
||||
DecorationCount = 240,
|
||||
RadiusOffset = 422000000f,
|
||||
RadiusVariance = 180000000f,
|
||||
HeightVariance = 22000000f,
|
||||
},
|
||||
ResourceNodes =
|
||||
[
|
||||
new ResourceNodeDefinition { SourceKind = "asteroid-belt", Angle = 0.2f, RadiusOffset = 126000f, InclinationDegrees = 4f, AnchorPlanetIndex = 3, OreAmount = 1000f, ItemId = "ore", ShardCount = 9 },
|
||||
new ResourceNodeDefinition { SourceKind = "asteroid-belt", Angle = 1.8f, RadiusOffset = 148000f, InclinationDegrees = -6f, AnchorPlanetIndex = 3, OreAmount = 1000f, ItemId = "ore", ShardCount = 9 },
|
||||
new ResourceNodeDefinition { SourceKind = "asteroid-belt", Angle = 3.5f, RadiusOffset = 138000f, InclinationDegrees = 8f, AnchorPlanetIndex = 4, OreAmount = 1000f, ItemId = "ore", ShardCount = 9 },
|
||||
new ResourceNodeDefinition { SourceKind = "asteroid-belt", Angle = 5.1f, RadiusOffset = 164000f, InclinationDegrees = -5f, AnchorPlanetIndex = 4, OreAmount = 1000f, ItemId = "ore", ShardCount = 9 },
|
||||
],
|
||||
Planets =
|
||||
[
|
||||
CreateSolPlanet("Mercury", "barren", "sphere", 0, mercuryOrbitAu, 0.2056f, 7.0f, 48f, 29f, 252f, "#b7a08f", 0.03f, false),
|
||||
CreateSolPlanet("Venus", "desert", "sphere", 0, venusOrbitAu, 0.0067f, 3.4f, 76f, 54f, 181f, "#d9b38c", 2.64f, false),
|
||||
CreateSolPlanet("Earth", "terrestrial", "sphere", 1, earthOrbitAu, 0.0167f, 0.0f, 0f, 114f, 100f, "#4f84c4", 0.41f, false),
|
||||
CreateSolPlanet("Mars", "desert", "sphere", 2, marsOrbitAu, 0.0934f, 1.85f, 49f, 286f, 54f, "#c56e52", 0.44f, false),
|
||||
CreateSolPlanet("Jupiter", "gas-giant", "oblate", 95, jupiterOrbitAu, 0.0489f, 1.3f, 100f, 275f, 34f, "#d9b06f", 0.05f, true),
|
||||
CreateSolPlanet("Saturn", "gas-giant", "oblate", 146, saturnOrbitAu, 0.0565f, 2.49f, 113f, 339f, 200f, "#dfc27d", 0.47f, true),
|
||||
CreateSolPlanet("Uranus", "ice-giant", "oblate", 28, uranusOrbitAu, 0.046f, 0.77f, 74f, 97f, 130f, "#9fd3df", 1.71f, true),
|
||||
CreateSolPlanet("Neptune", "ice-giant", "oblate", 16, neptuneOrbitAu, 0.009f, 1.77f, 132f, 273f, 256f, "#4c79c9", 0.49f, true)
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
private static PlanetDefinition CreateSolPlanet(
|
||||
string label,
|
||||
string planetType,
|
||||
string shape,
|
||||
int moonCount,
|
||||
float orbitRadiusAu,
|
||||
float orbitEccentricity,
|
||||
float orbitInclination,
|
||||
float ascendingNode,
|
||||
float argumentOfPeriapsis,
|
||||
float phaseAtEpoch,
|
||||
string color,
|
||||
float tilt,
|
||||
bool hasRing)
|
||||
{
|
||||
return new PlanetDefinition
|
||||
{
|
||||
Label = label,
|
||||
PlanetType = planetType,
|
||||
Shape = shape,
|
||||
MoonCount = moonCount,
|
||||
OrbitRadius = orbitRadiusAu,
|
||||
OrbitSpeed = ComputeSolOrbitSpeed(orbitRadiusAu),
|
||||
OrbitEccentricity = orbitEccentricity,
|
||||
OrbitInclination = orbitInclination,
|
||||
OrbitLongitudeOfAscendingNode = ascendingNode,
|
||||
OrbitArgumentOfPeriapsis = argumentOfPeriapsis,
|
||||
OrbitPhaseAtEpoch = phaseAtEpoch,
|
||||
Size = planetType switch
|
||||
{
|
||||
"gas-giant" => label == "Saturn" ? 58232f : 69911f,
|
||||
"ice-giant" => label == "Uranus" ? 25362f : 24622f,
|
||||
_ => label switch
|
||||
{
|
||||
"Mercury" => 2440f,
|
||||
"Venus" => 6052f,
|
||||
"Earth" => 6371f,
|
||||
"Mars" => 3390f,
|
||||
_ => 5000f,
|
||||
},
|
||||
},
|
||||
Color = color,
|
||||
Tilt = tilt,
|
||||
HasRing = hasRing,
|
||||
};
|
||||
}
|
||||
|
||||
private static float ComputeSolOrbitSpeed(float orbitRadiusAu)
|
||||
{
|
||||
const float earthAngularSpeed = 0.11f;
|
||||
return earthAngularSpeed / MathF.Sqrt(orbitRadiusAu * orbitRadiusAu * orbitRadiusAu);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user