mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-07-12 18:43:49 +00:00
docs(*): Add in physics formulae so I remember vaguely what I was trying to do
This commit is contained in:
+44
-4
@@ -28,9 +28,13 @@ func _ready():
|
|||||||
gravity_scale = 1.0
|
gravity_scale = 1.0
|
||||||
|
|
||||||
# Set custom inertia for better rotation
|
# Set custom inertia for better rotation
|
||||||
|
# Physics: I = m * r² (moment of inertia = mass × radius²)
|
||||||
|
# Lower inertia = easier to rotate, higher inertia = more stable
|
||||||
inertia = Vector3(1.0, 1.0, 1.0)
|
inertia = Vector3(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
# Create and apply low-friction physics material
|
# Create and apply low-friction physics material
|
||||||
|
# Physics: F_friction = μ * N (friction force = coefficient × normal force)
|
||||||
|
# Lower μ (friction coefficient) = less resistance to sliding
|
||||||
var ship_material = PhysicsMaterial.new()
|
var ship_material = PhysicsMaterial.new()
|
||||||
ship_material.friction = 0.1 # Very low friction
|
ship_material.friction = 0.1 # Very low friction
|
||||||
ship_material.bounce = 0.2 # Slight bounce
|
ship_material.bounce = 0.2 # Slight bounce
|
||||||
@@ -73,17 +77,25 @@ func _update_camera(delta):
|
|||||||
|
|
||||||
func _update_ball_cam(delta):
|
func _update_ball_cam(delta):
|
||||||
# In ball cam, camera positions itself so the ship is between camera and ball
|
# In ball cam, camera positions itself so the ship is between camera and ball
|
||||||
|
# Physics: Vector mathematics for 3D positioning
|
||||||
var ship_pos = global_transform.origin
|
var ship_pos = global_transform.origin
|
||||||
var ball_pos = ball.global_transform.origin
|
var ball_pos = ball.global_transform.origin
|
||||||
|
|
||||||
# Calculate direction from ball to ship
|
# Calculate direction from ball to ship
|
||||||
|
# Physics: Vector subtraction and normalization
|
||||||
|
# Direction vector: d̂ = (P₂ - P₁) / |P₂ - P₁|
|
||||||
var ball_to_ship = (ship_pos - ball_pos).normalized()
|
var ball_to_ship = (ship_pos - ball_pos).normalized()
|
||||||
|
|
||||||
# Position camera behind the ship relative to the ball's position
|
# Position camera behind the ship relative to the ball's position
|
||||||
# This ensures the ship is always between the camera and ball
|
# This ensures the ship is always between the camera and ball
|
||||||
|
# Physics: Vector addition for position calculation
|
||||||
|
# P_camera = P_ship + d̂ * distance + height_offset
|
||||||
var camera_target_pos = ship_pos + ball_to_ship * camera_distance + Vector3.UP * camera_height
|
var camera_target_pos = ship_pos + ball_to_ship * camera_distance + Vector3.UP * camera_height
|
||||||
|
|
||||||
# Smoothly move camera to target position
|
# Smoothly move camera to target position
|
||||||
|
# Physics: Linear interpolation (LERP) for smooth motion
|
||||||
|
# P(t) = P₀ + t * (P₁ - P₀), where t ∈ [0,1]
|
||||||
|
# This creates exponential approach to target position
|
||||||
camera.global_transform.origin = camera.global_transform.origin.lerp(camera_target_pos, camera_smoothing * delta)
|
camera.global_transform.origin = camera.global_transform.origin.lerp(camera_target_pos, camera_smoothing * delta)
|
||||||
|
|
||||||
# Make camera look at the ball
|
# Make camera look at the ball
|
||||||
@@ -93,11 +105,17 @@ func _update_ball_cam(delta):
|
|||||||
var to_ball = (ball_pos - camera_pos).normalized()
|
var to_ball = (ball_pos - camera_pos).normalized()
|
||||||
|
|
||||||
# Create look-at transform manually
|
# Create look-at transform manually
|
||||||
|
# Physics: 3D rotation matrices and basis vectors
|
||||||
|
# Uses right-hand rule: forward = -Z, up = Y, right = X
|
||||||
|
# Basis matrix transforms local coordinates to world coordinates
|
||||||
var camera_transform = Transform3D()
|
var camera_transform = Transform3D()
|
||||||
camera_transform.origin = camera_pos
|
camera_transform.origin = camera_pos
|
||||||
camera_transform.basis = Basis.looking_at(to_ball, Vector3.UP)
|
camera_transform.basis = Basis.looking_at(to_ball, Vector3.UP)
|
||||||
|
|
||||||
# Apply the rotation smoothly
|
# Apply the rotation smoothly
|
||||||
|
# Physics: Spherical linear interpolation (SLERP) for rotation
|
||||||
|
# SLERP provides smooth rotation along great circle on unit sphere
|
||||||
|
# Maintains constant angular velocity during interpolation
|
||||||
camera.global_transform.basis = camera.global_transform.basis.slerp(camera_transform.basis, camera_smoothing * delta)
|
camera.global_transform.basis = camera.global_transform.basis.slerp(camera_transform.basis, camera_smoothing * delta)
|
||||||
|
|
||||||
func _update_ship_cam(delta):
|
func _update_ship_cam(delta):
|
||||||
@@ -180,10 +198,15 @@ func apply_thruster_forces(state: PhysicsDirectBodyState3D, thrust_input: Vector
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Convert thrust input to world space forces based on ship orientation
|
# Convert thrust input to world space forces based on ship orientation
|
||||||
|
# Physics: F = m * a (Newton's Second Law: Force = mass × acceleration)
|
||||||
|
# World force = Local force × Rotation matrix (basis transformation)
|
||||||
var ship_basis = global_transform.basis
|
var ship_basis = global_transform.basis
|
||||||
var world_thrust = Vector3.ZERO
|
var world_thrust = Vector3.ZERO
|
||||||
|
|
||||||
# All thrusters should work relative to ship orientation
|
# All thrusters should work relative to ship orientation
|
||||||
|
# Physics: Vector transformation from local to world coordinates
|
||||||
|
# F_world = R * F_local (where R is rotation matrix)
|
||||||
|
|
||||||
# Forward/backward thrust (main engines)
|
# Forward/backward thrust (main engines)
|
||||||
world_thrust += -ship_basis.z * thrust_input.z * thrust_power
|
world_thrust += -ship_basis.z * thrust_input.z * thrust_power
|
||||||
|
|
||||||
@@ -199,6 +222,7 @@ func apply_thruster_forces(state: PhysicsDirectBodyState3D, thrust_input: Vector
|
|||||||
world_thrust *= turbo_multiplier
|
world_thrust *= turbo_multiplier
|
||||||
|
|
||||||
# Apply the force
|
# Apply the force
|
||||||
|
# Physics: Δv = F * Δt / m (change in velocity = force × time / mass)
|
||||||
state.apply_central_force(world_thrust)
|
state.apply_central_force(world_thrust)
|
||||||
|
|
||||||
func apply_rotation_forces(state: PhysicsDirectBodyState3D, rotation_input: Vector3):
|
func apply_rotation_forces(state: PhysicsDirectBodyState3D, rotation_input: Vector3):
|
||||||
@@ -206,19 +230,29 @@ func apply_rotation_forces(state: PhysicsDirectBodyState3D, rotation_input: Vect
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Apply torque for rotation - simple and effective
|
# Apply torque for rotation - simple and effective
|
||||||
|
# Physics: τ = I * α (torque = moment of inertia × angular acceleration)
|
||||||
|
# Also: α = τ / I (angular acceleration = torque / moment of inertia)
|
||||||
|
# Lower inertia = higher angular acceleration for same torque
|
||||||
var torque = Vector3(
|
var torque = Vector3(
|
||||||
rotation_input.x * rotation_power, # Pitch
|
rotation_input.x * rotation_power, # Pitch (rotation around X-axis)
|
||||||
rotation_input.y * rotation_power, # Yaw
|
rotation_input.y * rotation_power, # Yaw (rotation around Y-axis)
|
||||||
rotation_input.z * rotation_power # Roll
|
rotation_input.z * rotation_power # Roll (rotation around Z-axis)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Physics: Δω = τ * Δt / I (change in angular velocity = torque × time / inertia)
|
||||||
state.apply_torque(torque)
|
state.apply_torque(torque)
|
||||||
|
|
||||||
func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vector3):
|
func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vector3):
|
||||||
# Linear drag (air resistance)
|
# Linear drag (air resistance)
|
||||||
|
# Physics: F_drag = -½ * ρ * v² * C_d * A (drag force equation)
|
||||||
|
# Simplified: v_new = v_old * drag_coefficient (exponential decay)
|
||||||
|
# This simulates air resistance reducing velocity over time
|
||||||
state.linear_velocity *= drag_coefficient
|
state.linear_velocity *= drag_coefficient
|
||||||
|
|
||||||
# Angular drag (rotational resistance) - more aggressive when not rotating
|
# Angular drag (rotational resistance)
|
||||||
|
# Physics: Similar to linear drag but for rotational motion
|
||||||
|
# τ_drag = -C_angular * ω² (angular drag torque)
|
||||||
|
# Simplified: ω_new = ω_old * angular_drag (exponential decay)
|
||||||
if rotation_input.length() < 0.01:
|
if rotation_input.length() < 0.01:
|
||||||
# More drag when not actively rotating to stop quicker
|
# More drag when not actively rotating to stop quicker
|
||||||
state.angular_velocity *= 0.9
|
state.angular_velocity *= 0.9
|
||||||
@@ -227,8 +261,14 @@ func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vect
|
|||||||
state.angular_velocity *= angular_drag
|
state.angular_velocity *= angular_drag
|
||||||
|
|
||||||
# Limit maximum speeds
|
# Limit maximum speeds
|
||||||
|
# Physics: Terminal velocity concept - maximum achievable speed
|
||||||
|
# When thrust force = drag force, acceleration = 0, velocity = constant
|
||||||
if state.linear_velocity.length() > max_speed:
|
if state.linear_velocity.length() > max_speed:
|
||||||
|
# Normalize to unit vector, then scale to max speed
|
||||||
|
# Physics: v̂ = v / |v| (unit vector), v_limited = v̂ * v_max
|
||||||
state.linear_velocity = state.linear_velocity.normalized() * max_speed
|
state.linear_velocity = state.linear_velocity.normalized() * max_speed
|
||||||
|
|
||||||
if state.angular_velocity.length() > max_angular_speed:
|
if state.angular_velocity.length() > max_angular_speed:
|
||||||
|
# Same concept for angular velocity
|
||||||
|
# Physics: ω̂ = ω / |ω|, ω_limited = ω̂ * ω_max
|
||||||
state.angular_velocity = state.angular_velocity.normalized() * max_angular_speed
|
state.angular_velocity = state.angular_velocity.normalized() * max_angular_speed
|
||||||
|
|||||||
Reference in New Issue
Block a user