Camera adjusts to gravity normal

This commit is contained in:
Rob Kelly 2024-12-07 18:53:16 -07:00
parent 317f77c358
commit bfe2ca46d4
4 changed files with 52 additions and 5 deletions

View File

@ -38,6 +38,8 @@ const MAGNUS_EPSILON := 1e-3
## Scaling factor for additional force-based damage
@export var damage_force_scale := 0.01
var current_gravity: Vector3
var _last_contact_normal: Vector3 = Vector3.UP
var _position_on_last_wake: Vector3
var _awake := false
@ -80,6 +82,7 @@ func _magnus_force() -> Vector3:
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
current_gravity = state.total_gravity
if not _awake:
# Triggered on first frame after waking
_awake = true

View File

@ -49,6 +49,7 @@ const WIDTH := 4
@export var draw_reoriented_basis := true
@export var draw_magnus_effect := true
@export var draw_gravity_basis := true
@onready var physics_ball: GameBall = $\"..\"
@ -73,6 +74,19 @@ func _draw() -> void:
if draw_magnus_effect:
var end := camera.unproject_position(physics_ball.global_position + physics_ball._magnus_force() * MAGNUS_SCALE)
draw_line(start, end, COLOR_MAGNUS, WIDTH)
if draw_gravity_basis:
var orbital: Node3D = camera.get_parent_node_3d().get_parent_node_3d().get_parent_node_3d()
var up := -physics_ball.current_gravity.normalized()
var right := up.cross(orbital.global_basis.z).normalized()
var forward := right.cross(up).normalized()
var end_x := camera.unproject_position(physics_ball.global_position + right)
var end_y := camera.unproject_position(physics_ball.global_position + up)
var end_z := camera.unproject_position(physics_ball.global_position + forward)
draw_line(start, end_x, COLOR_X, WIDTH)
draw_line(start, end_y, COLOR_Y, WIDTH)
draw_line(start, end_z, COLOR_Z, WIDTH)
"
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_gc38m"]
@ -150,6 +164,7 @@ grow_horizontal = 2
grow_vertical = 2
script = SubResource("GDScript_p4v7o")
draw_reoriented_basis = false
draw_magnus_effect = false
[node name="SFX" type="Node3D" parent="."]
unique_name_in_owner = true

View File

@ -1,28 +1,49 @@
class_name OrbitalCamera extends Node3D
const POSITION_ACCELERATION := 4.0
const BASIS_ACCELERATION := 4.0
const TARGETER_ACCELERATION := 7.0
@export var target: Node3D
@export var offset := Vector3(0, 1, 0)
@export var angular_speed := 0.007
var target_basis := Basis.IDENTITY
@onready var pivot: Node3D = %Pivot
@onready var camera: Camera3D = %Camera
@onready var targeter: Node3D = %Targeter
static var scene := preload("res://src/ui/camera/orbital_camera/orbital_camera.tscn")
func _physics_process(delta: float) -> void:
var up := Vector3.UP
# If target is a game ball, realign to gravity
if target is GameBall:
up = -(target as GameBall).current_gravity.normalized()
var right := up.cross(global_basis.z).normalized()
var forward := right.cross(up).normalized()
target_basis = Basis(right, up, forward)
# Slerp to basis
global_basis = global_basis.slerp(target_basis, delta * BASIS_ACCELERATION)
# Update position
global_position = global_position.lerp(
target.global_position + offset, delta * POSITION_ACCELERATION
)
# Update rotation
camera.look_at(target.global_position)
#camera.look_at(target.global_position, up)
targeter.look_at(target.global_position, up)
camera.global_basis = camera.global_basis.slerp(
targeter.global_basis.orthonormalized(), delta * TARGETER_ACCELERATION
)
# Update phase angle
rotation.y += angular_speed
pivot.rotation.y += angular_speed
static func create(_target: Node3D) -> OrbitalCamera:

View File

@ -5,12 +5,20 @@
[node name="OrbitalCamera" type="Node3D"]
script = ExtResource("1_nvlic")
[node name="Pitch" type="SpringArm3D" parent="."]
[node name="Pivot" type="Node3D" parent="."]
unique_name_in_owner = true
[node name="Pitch" type="SpringArm3D" parent="Pivot"]
transform = Transform3D(1, 0, 0, 0, 0.913545, 0.406737, 0, -0.406737, 0.913545, 0, 0, 0)
spring_length = 3.2
[node name="Camera" type="Camera3D" parent="Pitch"]
unique_name_in_owner = true
[node name="CameraOffset" type="Node3D" parent="Pivot/Pitch"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3)
[node name="Targeter" type="Node3D" parent="Pivot/Pitch/CameraOffset"]
unique_name_in_owner = true
[node name="Camera" type="Camera3D" parent="Pivot/Pitch/CameraOffset"]
unique_name_in_owner = true
current = true
far = 8192.0