Improved animation performance

This commit is contained in:
2024-02-28 12:15:58 +01:00
parent ded6f51c5d
commit cb4dd41358
9 changed files with 63 additions and 52 deletions

View File

@ -0,0 +1,36 @@
class_name AnimationPerformance
const DELAY_INVISIBLE := 1.0
const DELAY_VISIBLE := 0.5
static var quality_budget: Array[int] = [
10, # Full animation quality
5, # 2.5 ms delay
5, # 5.0 ms delay
5, # 7.5 ms delay
5, # 10.0 ms delay
5, # 12.5 ms delay
5, # 15 ms delay
5, # 17.5 ms delay
5, # 20 ms delay
]
static func update_animation_quality(visible_players: Array[Player]):
var delay := 0.0
var count := 0
var index := 0
for player in visible_players:
if index >= quality_budget.size():
player.performance.delay_visible = DELAY_VISIBLE
player.animation.delay = DELAY_VISIBLE
continue
player.performance.delay_visible = delay
player.animation.delay = delay
count += 1
if count >= quality_budget[index]:
index += 1
delay += 0.025
count = 0

View File

@ -1,25 +1,11 @@
class_name PerformanceComponent
extends VisibleOnScreenNotifier3D
const SKIP_FRAMES_INVISIBLE := 16
const SKIP_FRAMES_VISIBLE := 8
static var quality_budget: Array[int] = [
10, # 0 skipped frames
10, # 1 skipped frame
10, # 2 skipped frames
10, # 3 skipped frames
10, # 4 skipped frames
10, # 5 skipped frames
10, # 6 skipped frames
10, # 7 skipped frames
]
@export var animation: AnimationComponent
var camera_distance_squared: float
var on_screen: bool
var skip_frames_visible: int
var delay_visible: float
func _ready():
assert(animation)
@ -28,13 +14,13 @@ func _ready():
func on_screen_entered():
on_screen = true
animation.skip_frames = skip_frames_visible
animation.delay = delay_visible
func on_screen_exited():
on_screen = false
animation.skip_frames = SKIP_FRAMES_INVISIBLE
animation.delay = AnimationPerformance.DELAY_INVISIBLE
static func update_all_animations():
static func get_visible_players_sorted_by_distance() -> Array[Player]:
var visible_players: Array[Player] = []
for player in Global.players.id_to_player.values():
@ -43,30 +29,13 @@ static func update_all_animations():
if player.performance.on_screen:
visible_players.append(player)
else:
player.performance.animation.skip_frames = SKIP_FRAMES_INVISIBLE
player.performance.animation.delay = AnimationPerformance.DELAY_INVISIBLE
if Global.player:
Global.player.performance.camera_distance_squared = 0
visible_players.sort_custom(PerformanceComponent.distance_sort)
var skip_frames := 0
var count := 0
for player in visible_players:
if skip_frames >= quality_budget.size():
player.performance.skip_frames_visible = SKIP_FRAMES_VISIBLE
player.animation.skip_frames = SKIP_FRAMES_VISIBLE
continue
player.performance.skip_frames_visible = skip_frames
player.animation.skip_frames = skip_frames
count += 1
if count >= quality_budget[skip_frames]:
skip_frames += 1
count = 0
return visible_players
static func distance_sort(a: Player, b: Player) -> bool:
return a.performance.camera_distance_squared < b.performance.camera_distance_squared
return a.performance.camera_distance_squared < b.performance.camera_distance_squared