diff options
author | metamuffin <metamuffin@disroot.org> | 2025-09-03 19:22:50 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-09-03 19:22:58 +0200 |
commit | 27a7ac2cb3935d4429d339b8ce8ee52a5c57e08b (patch) | |
tree | 085601b9c6fc42170db98bc6fe7c36d911e5e06c /client | |
parent | afe8d32818444c7df6702191dbf06f7dda240daa (diff) | |
download | hurrycurry-27a7ac2cb3935d4429d339b8ce8ee52a5c57e08b.tar hurrycurry-27a7ac2cb3935d4429d339b8ce8ee52a5c57e08b.tar.bz2 hurrycurry-27a7ac2cb3935d4429d339b8ce8ee52a5c57e08b.tar.zst |
add camera motion recording tool
Diffstat (limited to 'client')
-rw-r--r-- | client/player/camera_recorder.gd | 92 | ||||
-rw-r--r-- | client/player/camera_recorder.gd.uid | 1 | ||||
-rw-r--r-- | client/player/follow_camera.tscn | 6 |
3 files changed, 98 insertions, 1 deletions
diff --git a/client/player/camera_recorder.gd b/client/player/camera_recorder.gd new file mode 100644 index 00000000..8f398c2b --- /dev/null +++ b/client/player/camera_recorder.gd @@ -0,0 +1,92 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Node + +@export var record: bool = false +@export var replay: bool = false +@export_file var recording_path: String = "" + +@onready var camera: Camera3D = $".." + +var time = 0. +var keyframes = [] # Array<[float, Transform3D]> + +func _ready() -> void: + if record and replay: return push_error("concurrent ecord and replay is not supported") + if replay: load_recording() + +func _exit_tree() -> void: + if record: save_recording() + +func load_recording(): + print("Loading replay...") + var file := FileAccess.open(recording_path, FileAccess.READ) + var text := file.get_as_text() + keyframes.clear() + for line in text.split("\n"): + if line == "": continue + var toks = line.split(",") + var time2 = float(toks[0]) + var transform = parse_transform(toks[1]) + var fov = float(toks[2]) + keyframes.push_back([time2, transform, fov]) + print("Done") + +func save_recording(): + print("Saving replay...") + var file := FileAccess.open(recording_path, FileAccess.WRITE) + var out = "" + for k in keyframes: + out += "%f,%s,%f\n" % [k[0], serialize_transform(k[1]), k[2]] + file.store_string(out) + print("Done") + +func serialize_transform(t: Transform3D) -> String: + return "%f|%f|%f|%f|%f|%f|%f|%f|%f|%f|%f|%f" % [ + t.basis.x.x, t.basis.y.x, t.basis.z.x, t.origin.x, + t.basis.x.y, t.basis.y.y, t.basis.z.y, t.origin.y, + t.basis.x.z, t.basis.y.z, t.basis.z.z, t.origin.z, + ] + +func parse_transform(s: String) -> Transform3D: + var c := s.split("|") + var t := Transform3D.IDENTITY + t.basis.x.x = float(c[0]) + t.basis.y.x = float(c[1]) + t.basis.z.x = float(c[2]) + t.origin.x = float(c[3]) + t.basis.x.y = float(c[4]) + t.basis.y.y = float(c[5]) + t.basis.z.y = float(c[6]) + t.origin.y = float(c[7]) + t.basis.x.z = float(c[8]) + t.basis.y.z = float(c[9]) + t.basis.z.z = float(c[10]) + t.origin.z = float(c[11]) + return t + +func _process(dt: float): + if Global.game_paused: return + time += dt + if record: keyframes.push_back([time, camera.global_transform, camera.fov]) + if replay: + var index = keyframes.bsearch_custom([time], func (a, b): return a[0] < b[0]) + if index >= keyframes.size(): return + var from = keyframes[max(0, index - 1)] + var to = keyframes[index] + var t = (time - from[0]) / (to[0] - from[0]) + camera.global_transform = from[1].interpolate_with(to[1], t) + camera.fov = from[2] * (1. - t) + to[2] * t diff --git a/client/player/camera_recorder.gd.uid b/client/player/camera_recorder.gd.uid new file mode 100644 index 00000000..8d312732 --- /dev/null +++ b/client/player/camera_recorder.gd.uid @@ -0,0 +1 @@ +uid://b7wqp72o1bxvu diff --git a/client/player/follow_camera.tscn b/client/player/follow_camera.tscn index f753aad0..ac0040c9 100644 --- a/client/player/follow_camera.tscn +++ b/client/player/follow_camera.tscn @@ -1,7 +1,11 @@ -[gd_scene load_steps=2 format=3 uid="uid://b31mlnao6ybt8"] +[gd_scene load_steps=3 format=3 uid="uid://b31mlnao6ybt8"] [ext_resource type="Script" uid="uid://eieoab04mpqc" path="res://player/follow_camera.gd" id="1_qipju"] +[ext_resource type="Script" uid="uid://b7wqp72o1bxvu" path="res://player/camera_recorder.gd" id="2_12um7"] [node name="FollowCamera" type="Camera3D"] fov = 45.0 script = ExtResource("1_qipju") + +[node name="CameraRecorder" type="Node" parent="."] +script = ExtResource("2_12um7") |