From 4c3905422fc98eb20e72552d30c7ec028ab2a396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy?= <31370477+BarthPaleologue@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:35:23 +0100 Subject: [PATCH] apply tidal locking formulas to satellites --- src/ts/alphaTestis.ts | 2 +- .../telluricPlanet/telluricSatelliteModel.ts | 73 +++++++++++-------- src/ts/starSystem/seededStarSystemModel.ts | 2 +- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/ts/alphaTestis.ts b/src/ts/alphaTestis.ts index f4366f4e..8596c9c3 100644 --- a/src/ts/alphaTestis.ts +++ b/src/ts/alphaTestis.ts @@ -83,7 +83,7 @@ const spaceStationModel = newSeededSpaceElevatorModel(0, [sunModel], systemCoord physicsViewer.showBody(landingpad.aggregate.body); }*/ -const moonModel = newSeededTelluricSatelliteModel(23, "Manaleth", [hecateModel]); +const moonModel = newSeededTelluricSatelliteModel(23, "Manaleth", [hecateModel], [sunModel]); moonModel.physics.mass = 2; moonModel.physics.siderealDayDuration = 28 * 60 * 60; moonModel.physics.minTemperature = -180; diff --git a/src/ts/planets/telluricPlanet/telluricSatelliteModel.ts b/src/ts/planets/telluricPlanet/telluricSatelliteModel.ts index 68e2be95..4eedad3e 100644 --- a/src/ts/planets/telluricPlanet/telluricSatelliteModel.ts +++ b/src/ts/planets/telluricPlanet/telluricSatelliteModel.ts @@ -23,18 +23,24 @@ import { GenerationSteps } from "../../utils/generationSteps"; import { Settings } from "../../settings"; import { TelluricPlanetaryMassObjectPhysicsInfo } from "../../architecture/physicsInfo"; import { Quaternion } from "@babylonjs/core/Maths/math"; -import { Axis } from "@babylonjs/core/Maths/math.axis"; import { clamp } from "terrain-generation"; import { getOrbitalPeriod, getPeriapsis, Orbit } from "../../orbit/orbit"; -import { hasLiquidWater } from "../../utils/physics"; +import { getCurrentUniverseYear, getTidalLockingTimescale, hasLiquidWater } from "../../utils/physics"; import { CloudsModel, newCloudsModel } from "../../clouds/cloudsModel"; import { TelluricPlanetaryMassObjectModel } from "./telluricPlanetaryMassObjectModel"; +import { StellarObjectModel } from "../../architecture/stellarObject"; +import { Lerp } from "@babylonjs/core/Maths/math.scalar.functions"; export type TelluricSatelliteModel = TelluricPlanetaryMassObjectModel & { readonly type: OrbitalObjectType.TELLURIC_SATELLITE; }; -export function newSeededTelluricSatelliteModel(seed: number, name: string, parentBodies: CelestialBodyModel[]): TelluricSatelliteModel { +export function newSeededTelluricSatelliteModel( + seed: number, + name: string, + parentBodies: CelestialBodyModel[], + parentStellarObjects: StellarObjectModel[] +): TelluricSatelliteModel { const rng = getRngFromSeed(seed); const isSatelliteOfTelluric = parentBodies.some((parent) => parent.type === OrbitalObjectType.TELLURIC_PLANET); @@ -59,6 +65,40 @@ export function newSeededTelluricSatelliteModel(seed: number, name: string, pare mass = Settings.EARTH_MASS * (radius / 6_371e3) ** 3; } + // Todo: do not hardcode + let orbitRadius = 2e9 + rng(GenerationSteps.ORBIT) * 15e9; + + const orbitalP = 2; //clamp(normalRandom(2.0, 0.3, this.rng, GenerationSteps.Orbit + 80), 0.7, 3.0); + + const parentMaxRadius = parentBodies.reduce((max, body) => Math.max(max, body.radius), 0); + + orbitRadius = parentMaxRadius * clamp(normalRandom(2.0, 0.3, rng, GenerationSteps.ORBIT), 1.2, 3.0); + orbitRadius += parentMaxRadius * clamp(normalRandom(10, 4, rng, GenerationSteps.ORBIT), 1, 50); + orbitRadius += 2.0 * Math.max(0, parentMaxRadius - getPeriapsis(orbitRadius, orbitalP)); + + // this average is an approximation of a quaternion average + // see https://math.stackexchange.com/questions/61146/averaging-quaternions + const parentAverageAxialTilt: Quaternion = parentBodies.reduce((sum, body) => sum.add(body.physics.axialTilt), Quaternion.Zero()); + parentAverageAxialTilt.scaleInPlace(1 / parentBodies.length); + parentAverageAxialTilt.normalize(); + + const parentMassSum = parentBodies.reduce((sum, body) => sum + body.physics.mass, 0); + const orbit: Orbit = { + radius: orbitRadius, + p: orbitalP, + period: getOrbitalPeriod(orbitRadius, parentMassSum), + orientation: parentAverageAxialTilt + }; + + const tidalLockingTimescale = getTidalLockingTimescale(parentMassSum, mass, orbitRadius, radius, 0); + + const parentMaxBirthYear = parentStellarObjects.reduce((max, body) => Math.max(max, body.birthYear), 0); + const currentAge = getCurrentUniverseYear() - parentMaxBirthYear; + + const tidalLockingFactor = Math.min(1, currentAge / tidalLockingTimescale); + + const siderealDayDuration = Lerp(60 * 60 * 24, orbit.period, tidalLockingFactor); + let pressure = Math.max(normalRandom(0.9, 0.2, rng, GenerationSteps.PRESSURE), 0); if (isSatelliteOfTelluric || radius <= 0.3 * Settings.EARTH_RADIUS) { pressure = 0; @@ -69,16 +109,10 @@ export function newSeededTelluricSatelliteModel(seed: number, name: string, pare // when pressure is close to 1, the max temperature is close to the min temperature (the atmosphere does thermal regulation) const maxTemperature = minTemperature + Math.exp(-pressure) * randRangeInt(30, 200, rng, 81); - // this average is an approximation of a quaternion average - // see https://math.stackexchange.com/questions/61146/averaging-quaternions - const parentAverageAxialTilt: Quaternion = parentBodies.reduce((sum, body) => sum.add(body.physics.axialTilt), Quaternion.Zero()); - parentAverageAxialTilt.scaleInPlace(1 / parentBodies.length); - parentAverageAxialTilt.normalize(); - const physicalProperties: TelluricPlanetaryMassObjectPhysicsInfo = { mass: mass, axialTilt: parentAverageAxialTilt, - siderealDayDuration: (60 * 60 * 24) / 10, + siderealDayDuration: siderealDayDuration, minTemperature: minTemperature, maxTemperature: maxTemperature, pressure: pressure, @@ -88,25 +122,6 @@ export function newSeededTelluricSatelliteModel(seed: number, name: string, pare physicalProperties.oceanLevel = Settings.OCEAN_DEPTH * physicalProperties.waterAmount * physicalProperties.pressure; - // Todo: do not hardcode - let orbitRadius = 2e9 + rng(GenerationSteps.ORBIT) * 15e9; - - const orbitalP = 2; //clamp(normalRandom(2.0, 0.3, this.rng, GenerationSteps.Orbit + 80), 0.7, 3.0); - - const parentMaxRadius = parentBodies.reduce((max, body) => Math.max(max, body.radius), 0); - - orbitRadius = parentMaxRadius * clamp(normalRandom(2.0, 0.3, rng, GenerationSteps.ORBIT), 1.2, 3.0); - orbitRadius += parentMaxRadius * clamp(normalRandom(10, 4, rng, GenerationSteps.ORBIT), 1, 50); - orbitRadius += 2.0 * Math.max(0, parentMaxRadius - getPeriapsis(orbitRadius, orbitalP)); - - const parentMassSum = parentBodies.reduce((sum, body) => sum + body.physics.mass, 0); - const orbit: Orbit = { - radius: orbitRadius, - p: orbitalP, - period: getOrbitalPeriod(orbitRadius, parentMassSum), - orientation: parentAverageAxialTilt - }; - // tidal lock physicalProperties.siderealDayDuration = orbit.period; diff --git a/src/ts/starSystem/seededStarSystemModel.ts b/src/ts/starSystem/seededStarSystemModel.ts index 564f273e..47c806d7 100644 --- a/src/ts/starSystem/seededStarSystemModel.ts +++ b/src/ts/starSystem/seededStarSystemModel.ts @@ -146,7 +146,7 @@ export function newSeededStarSystemModel(seed: SystemSeed): StarSystemModel { for (let j = 0; j < nbMoons; j++) { const satelliteName = `${planetarySystemName}${Alphabet[j]}`; const satelliteSeed = centeredRand(planetarySystemRng, GenerationSteps.MOONS + j) * Settings.SEED_HALF_RANGE; - const satelliteModel = newSeededTelluricSatelliteModel(satelliteSeed, satelliteName, planets); + const satelliteModel = newSeededTelluricSatelliteModel(satelliteSeed, satelliteName, planets, stellarObjects); satellites.push(satelliteModel); } });