- Added a save override confirmation in main menu. - Added Interaction types. - Added some test interactions. - Also added a ViewRollEffect for the player camera. - Also also added a cubemap generator (CubeMapGeneratorCamera).
109 lines
2.8 KiB
GDScript
109 lines
2.8 KiB
GDScript
@tool
|
|
class_name CubeMapGeneratorCamera
|
|
extends Camera3D
|
|
|
|
## https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html
|
|
|
|
const RESOLUTIONS: PackedInt32Array = [
|
|
2,
|
|
4,
|
|
8,
|
|
16,
|
|
32,
|
|
64,
|
|
128,
|
|
256,
|
|
512,
|
|
1024,
|
|
2048,
|
|
4096,
|
|
8192,
|
|
]
|
|
|
|
const AXIS_NAMES: Dictionary[int, String] = {
|
|
0: "Front", 1: "Left", 2: "Back", 3: "Right", 4: "Up", 5: "Down"
|
|
}
|
|
|
|
const CAMERA_ALIGNMENTS: Dictionary[int, Vector3] = {
|
|
0: Vector3.ZERO, # Forward
|
|
1: Vector3(0.0, -90.0, 0.0), # Left
|
|
2: Vector3(0.0, 180.0, 0.0), # Back
|
|
3: Vector3(0.0, 90.0, 0.0), # Right
|
|
4: Vector3(90.0, 90.0, 0.0), # Up
|
|
5: Vector3(-90.0, 90.0, 0.0),# Down
|
|
}
|
|
|
|
|
|
@warning_ignore("unused_private_class_variable")
|
|
@export_tool_button("Generate Cubemaps", "Cubemap") var _gen: Callable = generate_cubemaps
|
|
@export var resolution: int = 8
|
|
@export var msaa := SubViewport.MSAA.MSAA_8X
|
|
@export var ssaa := SubViewport.ScreenSpaceAA.SCREEN_SPACE_AA_SMAA
|
|
@export_global_dir var output_directory: String = "user://cubemaps/"
|
|
|
|
|
|
func _validate_property(property: Dictionary) -> void:
|
|
if property.name == "resolution":
|
|
var enums: String = str(RESOLUTIONS).replace("[", "").replace("]", "").replace(" ", "")
|
|
|
|
property.type = TYPE_INT
|
|
property.hint = PROPERTY_HINT_ENUM
|
|
property.hint_string = enums
|
|
|
|
|
|
func generate_cubemaps() -> void:
|
|
if not DirAccess.dir_exists_absolute(output_directory):
|
|
push_error("Directory '%s' does not exist. Please create it." % output_directory)
|
|
return
|
|
|
|
var camera: Camera3D = duplicate()
|
|
camera.fov = 90.0
|
|
|
|
for child: Node in camera.get_children():
|
|
child.queue_free()
|
|
|
|
var viewport := SubViewport.new()
|
|
viewport.msaa_3d = msaa
|
|
viewport.screen_space_aa = ssaa
|
|
viewport.size = get_resolution()
|
|
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
|
add_child(viewport)
|
|
viewport.owner = get_owner()
|
|
|
|
viewport.add_child(camera)
|
|
camera.owner = get_owner()
|
|
camera.global_position = global_position
|
|
camera.make_current()
|
|
|
|
for axis: int in range(6):
|
|
camera.rotation_degrees = CAMERA_ALIGNMENTS[axis]
|
|
await take_screenshot(viewport, axis)
|
|
#await get_tree().create_timer(3.0).timeout
|
|
|
|
#await get_tree().create_timer(15.0).timeout
|
|
|
|
viewport.queue_free()
|
|
|
|
|
|
func take_screenshot(viewport: SubViewport, axis_index: int) -> void:
|
|
await RenderingServer.frame_post_draw
|
|
var image: Image = viewport.get_texture().get_image()
|
|
|
|
var file: String = str(_get_scene_name(), "_", AXIS_NAMES[axis_index], ".png")
|
|
var filepath: String = output_directory.path_join(file)
|
|
|
|
image.save_png(filepath)
|
|
|
|
|
|
func get_resolution() -> Vector2i:
|
|
@warning_ignore("narrowing_conversion")
|
|
var _resolution: int = pow(2.0, 1 + resolution)
|
|
return Vector2i.ONE * _resolution
|
|
|
|
|
|
func _get_scene_name() -> String:
|
|
if Engine.is_editor_hint():
|
|
return Engine.get_singleton(&"EditorInterface").get_edited_scene_root().name
|
|
|
|
return owner.name
|