portal-transformations/portal_camera.gd

58 lines
1.5 KiB
GDScript

@tool
extends Camera3D
@export var home: Node3D
@export var target: Node3D
@export var portal_mesh: MeshInstance3D:
set(v):
portal_mesh = v
if v != null:
print("set: portal_mesh", v)
var mat = v.mesh.surface_get_material(0) as ShaderMaterial
mat.set_shader_parameter("albedo", get_parent().get_texture())
@export var player_camera: Node3D
@export_tool_button("Grab editor camera", "Camera3D")
var _tb_grab_editor_camera: Callable = _grab_editor_camera
func _ready() -> void:
if home == null:
var p = get_parent()
while p is not Node3D:
p = p.get_parent()
home = p
print(name + ": home = " + home.name)
var env: Environment = get_world_3d().environment.duplicate()
env.tonemap_mode = Environment.TONE_MAPPER_LINEAR
env.tonemap_exposure = 1
self.environment = env
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if not check():
return
var player_to_home = home.global_transform.affine_inverse() * player_camera.global_transform
var flipped = player_to_home.rotated(Vector3.UP, PI)
var relative_to_target = target.global_transform * flipped
self.global_transform = relative_to_target
func check() -> bool:
return target != null and \
player_camera != null and \
home != null and \
portal_mesh != null
func _grab_editor_camera() -> void:
if Engine.is_editor_hint():
print("Grabbing editor camera")
player_camera = EditorInterface.get_editor_viewport_3d(0).get_camera_3d()
else:
print("Not in editor - cannot grab editor camera!")