Improved animation performance
This commit is contained in:
parent
ded6f51c5d
commit
cb4dd41358
@ -11,6 +11,6 @@ var terrain: Terrain3D
|
|||||||
var instance_id: int
|
var instance_id: int
|
||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
instance_id = OS.get_process_id() % 2
|
instance_id = 0 #OS.get_process_id() % 2
|
||||||
account = Account.new()
|
account = Account.new()
|
||||||
account.name = "user%d" % instance_id
|
account.name = "user%d" % instance_id
|
||||||
|
@ -17,4 +17,8 @@ func on_jump():
|
|||||||
func handle_packet(data: PackedByteArray):
|
func handle_packet(data: PackedByteArray):
|
||||||
var player_id := data.get_string_from_ascii()
|
var player_id := data.get_string_from_ascii()
|
||||||
var player := Global.players.get_player(player_id)
|
var player := Global.players.get_player(player_id)
|
||||||
|
|
||||||
|
if !player:
|
||||||
|
return
|
||||||
|
|
||||||
player.controller.jumped.emit()
|
player.controller.jumped.emit()
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
class_name AnimationComponent
|
class_name AnimationComponent
|
||||||
extends CharacterComponent
|
extends CharacterComponent
|
||||||
|
|
||||||
@export var skip_frames: int = 0
|
|
||||||
|
|
||||||
var animations: AnimationPlayer
|
var animations: AnimationPlayer
|
||||||
var state: StateComponent
|
var state: StateComponent
|
||||||
var accumulated_delta: float
|
var accumulated_delta: float
|
||||||
var skipped_frames: int
|
var delay: float
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
state = character.get_node("State")
|
state = character.get_node("State")
|
||||||
@ -16,12 +14,9 @@ func _ready():
|
|||||||
func _process(delta: float):
|
func _process(delta: float):
|
||||||
accumulated_delta += delta
|
accumulated_delta += delta
|
||||||
|
|
||||||
if skipped_frames >= skip_frames:
|
if accumulated_delta >= delay:
|
||||||
animations.advance(accumulated_delta)
|
animations.advance(accumulated_delta)
|
||||||
accumulated_delta = 0
|
accumulated_delta = 0
|
||||||
skipped_frames = 0
|
|
||||||
else:
|
|
||||||
skipped_frames += 1
|
|
||||||
|
|
||||||
func on_transition(_from: StateComponent.State, to: StateComponent.State):
|
func on_transition(_from: StateComponent.State, to: StateComponent.State):
|
||||||
match to:
|
match to:
|
||||||
|
@ -15,8 +15,7 @@ var ik_time: float
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if owner != Global.player:
|
if owner != Global.player:
|
||||||
queue_free()
|
set_enabled(false)
|
||||||
return
|
|
||||||
|
|
||||||
for foot_name in feet_names:
|
for foot_name in feet_names:
|
||||||
var foot = Foot.new()
|
var foot = Foot.new()
|
||||||
@ -94,3 +93,7 @@ func get_foot_rotation(old: Basis, normal: Vector3) -> Basis:
|
|||||||
new = new.orthonormalized()
|
new = new.orthonormalized()
|
||||||
new = new.rotated(Vector3.UP, PI)
|
new = new.rotated(Vector3.UP, PI)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
func set_enabled(enabled: bool):
|
||||||
|
set_process(enabled)
|
||||||
|
set_physics_process(enabled)
|
||||||
|
@ -17,6 +17,9 @@ func _ready():
|
|||||||
character.controlled.connect(on_controlled)
|
character.controlled.connect(on_controlled)
|
||||||
|
|
||||||
func _process(delta: float):
|
func _process(delta: float):
|
||||||
|
if (physics_position - character.position).length_squared() < 0.00001:
|
||||||
|
return
|
||||||
|
|
||||||
character.position = Math.damp_vector(character.position, physics_position, ticks_per_second * delta)
|
character.position = Math.damp_vector(character.position, physics_position, ticks_per_second * delta)
|
||||||
|
|
||||||
func _physics_process(delta: float):
|
func _physics_process(delta: float):
|
||||||
|
36
client/player/performance/AnimationPerformance.gd
Normal file
36
client/player/performance/AnimationPerformance.gd
Normal 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
|
@ -1,25 +1,11 @@
|
|||||||
class_name PerformanceComponent
|
class_name PerformanceComponent
|
||||||
extends VisibleOnScreenNotifier3D
|
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
|
@export var animation: AnimationComponent
|
||||||
|
|
||||||
var camera_distance_squared: float
|
var camera_distance_squared: float
|
||||||
var on_screen: bool
|
var on_screen: bool
|
||||||
var skip_frames_visible: int
|
var delay_visible: float
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
assert(animation)
|
assert(animation)
|
||||||
@ -28,13 +14,13 @@ func _ready():
|
|||||||
|
|
||||||
func on_screen_entered():
|
func on_screen_entered():
|
||||||
on_screen = true
|
on_screen = true
|
||||||
animation.skip_frames = skip_frames_visible
|
animation.delay = delay_visible
|
||||||
|
|
||||||
func on_screen_exited():
|
func on_screen_exited():
|
||||||
on_screen = false
|
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] = []
|
var visible_players: Array[Player] = []
|
||||||
|
|
||||||
for player in Global.players.id_to_player.values():
|
for player in Global.players.id_to_player.values():
|
||||||
@ -43,30 +29,13 @@ static func update_all_animations():
|
|||||||
if player.performance.on_screen:
|
if player.performance.on_screen:
|
||||||
visible_players.append(player)
|
visible_players.append(player)
|
||||||
else:
|
else:
|
||||||
player.performance.animation.skip_frames = SKIP_FRAMES_INVISIBLE
|
player.performance.animation.delay = AnimationPerformance.DELAY_INVISIBLE
|
||||||
|
|
||||||
if Global.player:
|
if Global.player:
|
||||||
Global.player.performance.camera_distance_squared = 0
|
Global.player.performance.camera_distance_squared = 0
|
||||||
|
|
||||||
visible_players.sort_custom(PerformanceComponent.distance_sort)
|
visible_players.sort_custom(PerformanceComponent.distance_sort)
|
||||||
|
return visible_players
|
||||||
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
|
|
||||||
|
|
||||||
static func distance_sort(a: Player, b: Player) -> bool:
|
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
|
||||||
|
|
@ -10,7 +10,8 @@ func _ready():
|
|||||||
timer.timeout.connect(tick)
|
timer.timeout.connect(tick)
|
||||||
|
|
||||||
func tick():
|
func tick():
|
||||||
PerformanceComponent.update_all_animations()
|
var visible_players := PerformanceComponent.get_visible_players_sorted_by_distance()
|
||||||
|
AnimationPerformance.update_animation_quality(visible_players)
|
||||||
|
|
||||||
func add(player: Player):
|
func add(player: Player):
|
||||||
if has(player.id):
|
if has(player.id):
|
||||||
@ -20,7 +21,7 @@ func add(player: Player):
|
|||||||
id_to_player[player.id] = player
|
id_to_player[player.id] = player
|
||||||
|
|
||||||
func get_player(id: String) -> Player:
|
func get_player(id: String) -> Player:
|
||||||
return id_to_player[id] as Player
|
return id_to_player.get(id) as Player
|
||||||
|
|
||||||
func has(id: String) -> bool:
|
func has(id: String) -> bool:
|
||||||
return id_to_player.has(id)
|
return id_to_player.has(id)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SpawnPoint = Vector3{584.98, 9.5, 394.68}
|
SpawnPoint = Vector3{584.98, 9.8, 394.68}
|
||||||
accounts = map[string]*Account{}
|
accounts = map[string]*Account{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ func init() {
|
|||||||
func MakeTestAccounts() {
|
func MakeTestAccounts() {
|
||||||
for i := range 500 {
|
for i := range 500 {
|
||||||
angle := rand.Float64() * math.Pi * 2
|
angle := rand.Float64() * math.Pi * 2
|
||||||
distance := rand.Float64() * 12.0
|
distance := rand.Float64() * 25.0
|
||||||
|
|
||||||
accounts[fmt.Sprintf("user%d", i)] = &Account{
|
accounts[fmt.Sprintf("user%d", i)] = &Account{
|
||||||
ID: fmt.Sprintf("id%d", i),
|
ID: fmt.Sprintf("id%d", i),
|
||||||
|
Loading…
Reference in New Issue
Block a user