73 lines
2.7 KiB
GDScript
73 lines
2.7 KiB
GDScript
extends Spatial
|
|
class_name SolarSystem
|
|
|
|
const G = 6.674 * pow(10, -11)
|
|
|
|
# Because we're dealing with a miniature, we want small masses and distances to have noticeable
|
|
# gravitational effects. These multipliers adapt the scale of the game to an earth-like scale.
|
|
const mass_multiplier = pow(10, 24) # thus, the earth would get a mass of 6
|
|
const distance_multiplier = 318550 # thus, a radius of 20 results in an earth-like radius
|
|
|
|
# If the gravity doesn't feel like it should, this scales it. A higher value means that the pull is
|
|
# stronger.
|
|
const gravity_multiplier = 10.0
|
|
|
|
|
|
# Return the gravity acceleration vector to the closest planet, not taking all other planets into
|
|
# account.
|
|
# This is useful for keeping something firmly on the planet while it is touching it, or for creating
|
|
# a predictable orbit.
|
|
func get_closest_gravity_acceleration(position: Vector3) -> Vector3:
|
|
var closest_planet_distance = INF
|
|
var closest_force = 0.0
|
|
|
|
# Iterate through all planets to find the closest one
|
|
for planet in get_children():
|
|
var pos_to_center = (planet.transform.origin - position)
|
|
var distance = pos_to_center.length()
|
|
|
|
if distance < closest_planet_distance:
|
|
# This planet is closer than the previous ones -> calculate and save the values
|
|
var force = _gravity(planet.mass * mass_multiplier, distance * distance_multiplier)
|
|
force *= gravity_multiplier
|
|
|
|
# Multiply by the normalized vector towards the center to give the force a direction
|
|
closest_force = (pos_to_center / distance) * force
|
|
closest_planet_distance = distance
|
|
|
|
return closest_force
|
|
|
|
|
|
# Return the total gravity acceleration vector experienced at that position.
|
|
func get_gravity_acceleration(position: Vector3) -> Vector3:
|
|
var total_force = Vector3.ZERO
|
|
|
|
# Add each planet's gravity force to the total force
|
|
for planet in get_children():
|
|
var pos_to_center = (planet.transform.origin - position)
|
|
var distance = pos_to_center.length()
|
|
|
|
var force = _gravity(planet.mass * mass_multiplier, distance * distance_multiplier)
|
|
force *= gravity_multiplier
|
|
|
|
total_force += (pos_to_center / distance) * force
|
|
|
|
return total_force
|
|
|
|
|
|
# Return the velocity needed to orbit the given planet
|
|
func get_orbit_velocity(position: Vector3, planet):
|
|
var pos_to_center = (planet.global_transform.origin - position)
|
|
var distance = pos_to_center.length()
|
|
|
|
# raw_velocity is the velocity according to the formula, but we also need to account for the gravity_multiplier.
|
|
var raw_velocity = -sqrt((G * planet.mass * mass_multiplier) / (distance * distance_multiplier))
|
|
var gravity_scale_factor = sqrt(gravity_multiplier / distance_multiplier)
|
|
|
|
return raw_velocity * gravity_scale_factor
|
|
|
|
|
|
# Formula for gravity
|
|
static func _gravity(mass, distance):
|
|
return (G * mass) / (distance * distance)
|