Skip to content

Commit

Permalink
apply tidal locking formulas to satellites
Browse files Browse the repository at this point in the history
  • Loading branch information
BarthPaleologue committed Nov 3, 2024
1 parent 2af3033 commit 4c39054
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/ts/alphaTestis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
73 changes: 44 additions & 29 deletions src/ts/planets/telluricPlanet/telluricSatelliteModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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,
Expand All @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/ts/starSystem/seededStarSystemModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
Expand Down

0 comments on commit 4c39054

Please sign in to comment.