| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  |  | /*  voxel_gi_editor_plugin.cpp                                            */ | 
					
						
							|  |  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  |  | /*                                                                        */ | 
					
						
							|  |  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
					
						
							|  |  |  |  | /* a copy of this software and associated documentation files (the        */ | 
					
						
							|  |  |  |  | /* "Software"), to deal in the Software without restriction, including    */ | 
					
						
							|  |  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
					
						
							|  |  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
					
						
							|  |  |  |  | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
					
						
							|  |  |  |  | /* the following conditions:                                              */ | 
					
						
							|  |  |  |  | /*                                                                        */ | 
					
						
							|  |  |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							|  |  |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							|  |  |  |  | /*                                                                        */ | 
					
						
							|  |  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							|  |  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							|  |  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
					
						
							|  |  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
					
						
							|  |  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
					
						
							|  |  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
					
						
							|  |  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | #include "voxel_gi_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:46:22 +01:00
										 |  |  |  | #include "editor/editor_file_dialog.h"
 | 
					
						
							|  |  |  |  | #include "editor/editor_node.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::_bake() { | 
					
						
							|  |  |  |  | 	if (voxel_gi) { | 
					
						
							| 
									
										
										
										
											2022-04-29 07:06:48 +01:00
										 |  |  |  | 		Ref<VoxelGIData> voxel_gi_data = voxel_gi->get_probe_data(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (voxel_gi_data.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-09-30 16:30:55 +02:00
										 |  |  |  | 			String path = get_tree()->get_edited_scene_root()->get_scene_file_path(); | 
					
						
							| 
									
										
										
										
											2021-12-09 03:42:46 -06:00
										 |  |  |  | 			if (path.is_empty()) { | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 				path = "res://" + voxel_gi->get_name() + "_data.res"; | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 			} else { | 
					
						
							|  |  |  |  | 				String ext = path.get_extension(); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 				path = path.get_basename() + "." + voxel_gi->get_name() + "_data.res"; | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 			probe_file->set_current_path(path); | 
					
						
							| 
									
										
										
										
											2020-07-11 18:45:19 +02:00
										 |  |  |  | 			probe_file->popup_file_dialog(); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2022-04-29 07:06:48 +01:00
										 |  |  |  | 		} else { | 
					
						
							|  |  |  |  | 			String path = voxel_gi_data->get_path(); | 
					
						
							|  |  |  |  | 			if (!path.is_resource_file()) { | 
					
						
							|  |  |  |  | 				int srpos = path.find("::"); | 
					
						
							|  |  |  |  | 				if (srpos != -1) { | 
					
						
							|  |  |  |  | 					String base = path.substr(0, srpos); | 
					
						
							|  |  |  |  | 					if (ResourceLoader::get_resource_type(base) == "PackedScene") { | 
					
						
							|  |  |  |  | 						if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) { | 
					
						
							|  |  |  |  | 							EditorNode::get_singleton()->show_warning(TTR("Voxel GI data is not local to the scene.")); | 
					
						
							|  |  |  |  | 							return; | 
					
						
							|  |  |  |  | 						} | 
					
						
							|  |  |  |  | 					} else { | 
					
						
							|  |  |  |  | 						if (FileAccess::exists(base + ".import")) { | 
					
						
							|  |  |  |  | 							EditorNode::get_singleton()->show_warning(TTR("Voxel GI data is part of an imported resource.")); | 
					
						
							|  |  |  |  | 							return; | 
					
						
							|  |  |  |  | 						} | 
					
						
							|  |  |  |  | 					} | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} else { | 
					
						
							|  |  |  |  | 				if (FileAccess::exists(path + ".import")) { | 
					
						
							|  |  |  |  | 					EditorNode::get_singleton()->show_warning(TTR("Voxel GI data is an imported resource.")); | 
					
						
							|  |  |  |  | 					return; | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-29 07:06:48 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 		voxel_gi->bake(); | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::edit(Object *p_object) { | 
					
						
							|  |  |  |  | 	VoxelGI *s = Object::cast_to<VoxelGI>(p_object); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  |  | 	if (!s) { | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	voxel_gi = s; | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | bool VoxelGIEditorPlugin::handles(Object *p_object) const { | 
					
						
							|  |  |  |  | 	return p_object->is_class("VoxelGI"); | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 	switch (p_what) { | 
					
						
							|  |  |  |  | 		case NOTIFICATION_PROCESS: { | 
					
						
							|  |  |  |  | 			if (!voxel_gi) { | 
					
						
							|  |  |  |  | 				return; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			// Set information tooltip on the Bake button. This information is useful
 | 
					
						
							|  |  |  |  | 			// to optimize performance (video RAM size) and reduce light leaking (individual cell size).
 | 
					
						
							| 
									
										
										
										
											2021-12-05 20:07:13 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  |  | 			const Vector3i cell_size = voxel_gi->get_estimated_cell_size(); | 
					
						
							| 
									
										
										
										
											2021-12-05 20:07:13 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  |  | 			const Vector3 half_size = voxel_gi->get_size() / 2; | 
					
						
							| 
									
										
										
										
											2021-12-05 20:07:13 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			const int data_size = 4; | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  |  | 			const double size_mb = cell_size.x * cell_size.y * cell_size.z * data_size / (1024.0 * 1024.0); | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			// Add a qualitative measurement to help the user assess whether a VoxelGI node is using a lot of VRAM.
 | 
					
						
							|  |  |  |  | 			String size_quality; | 
					
						
							|  |  |  |  | 			if (size_mb < 16.0) { | 
					
						
							|  |  |  |  | 				size_quality = TTR("Low"); | 
					
						
							|  |  |  |  | 			} else if (size_mb < 64.0) { | 
					
						
							|  |  |  |  | 				size_quality = TTR("Moderate"); | 
					
						
							|  |  |  |  | 			} else { | 
					
						
							|  |  |  |  | 				size_quality = TTR("High"); | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			String text; | 
					
						
							| 
									
										
										
										
											2022-07-12 08:43:01 +01:00
										 |  |  |  | 			text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), cell_size.x, cell_size.y, cell_size.z)) + "\n"; | 
					
						
							|  |  |  |  | 			text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), half_size.x / cell_size.x, half_size.y / cell_size.y, half_size.z / cell_size.z)) + "\n"; | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality); | 
					
						
							| 
									
										
										
										
											2021-12-05 20:07:13 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 			// Only update the tooltip when needed to avoid constant redrawing.
 | 
					
						
							|  |  |  |  | 			if (bake->get_tooltip(Point2()) == text) { | 
					
						
							|  |  |  |  | 				return; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 12:42:17 +02:00
										 |  |  |  | 			bake->set_tooltip_text(text); | 
					
						
							| 
									
										
										
										
											2022-02-16 09:17:55 -05:00
										 |  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::make_visible(bool p_visible) { | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 	if (p_visible) { | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 		bake_hb->show(); | 
					
						
							|  |  |  |  | 		set_process(true); | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 		bake_hb->hide(); | 
					
						
							|  |  |  |  | 		set_process(false); | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | EditorProgress *VoxelGIEditorPlugin::tmp_progress = nullptr; | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::bake_func_begin(int p_steps) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  |  | 	ERR_FAIL_COND(tmp_progress != nullptr); | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 23:12:26 +01:00
										 |  |  |  | 	tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), p_steps)); | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::bake_func_step(int p_step, const String &p_description) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  |  | 	ERR_FAIL_COND(tmp_progress == nullptr); | 
					
						
							| 
									
										
										
										
											2018-01-12 00:08:32 -03:00
										 |  |  |  | 	tmp_progress->step(p_description, p_step, false); | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::bake_func_end() { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  |  | 	ERR_FAIL_COND(tmp_progress == nullptr); | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | 	memdelete(tmp_progress); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  |  | 	tmp_progress = nullptr; | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake(const String &p_path) { | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	probe_file->hide(); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	if (voxel_gi) { | 
					
						
							|  |  |  |  | 		voxel_gi->bake(); | 
					
						
							|  |  |  |  | 		ERR_FAIL_COND(voxel_gi->get_probe_data().is_null()); | 
					
						
							| 
									
										
										
										
											2022-06-03 01:33:42 +02:00
										 |  |  |  | 		ResourceSaver::save(voxel_gi->get_probe_data(), p_path, ResourceSaver::FLAG_CHANGE_PATH); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | void VoxelGIEditorPlugin::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 10:36:51 +01:00
										 |  |  |  | VoxelGIEditorPlugin::VoxelGIEditorPlugin() { | 
					
						
							| 
									
										
										
										
											2019-11-05 12:01:00 +01:00
										 |  |  |  | 	bake_hb = memnew(HBoxContainer); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); | 
					
						
							|  |  |  |  | 	bake_hb->hide(); | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  |  | 	bake = memnew(Button); | 
					
						
							|  |  |  |  | 	bake->set_flat(true); | 
					
						
							| 
									
										
										
										
											2022-01-27 10:36:51 +01:00
										 |  |  |  | 	bake->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons"))); | 
					
						
							| 
									
										
										
										
											2022-01-26 23:12:26 +01:00
										 |  |  |  | 	bake->set_text(TTR("Bake VoxelGI")); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake)); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	bake_hb->add_child(bake); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	voxel_gi = nullptr; | 
					
						
							| 
									
										
										
										
											2019-11-05 12:01:00 +01:00
										 |  |  |  | 	probe_file = memnew(EditorFileDialog); | 
					
						
							| 
									
										
										
										
											2020-03-06 14:00:16 -03:00
										 |  |  |  | 	probe_file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	probe_file->add_filter("*.res"); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	probe_file->connect("file_selected", callable_mp(this, &VoxelGIEditorPlugin::_voxel_gi_save_path_and_bake)); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  |  | 	get_editor_interface()->get_base_control()->add_child(probe_file); | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	probe_file->set_title(TTR("Select path for VoxelGI Data File")); | 
					
						
							| 
									
										
										
										
											2017-10-30 16:33:07 -03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | 	VoxelGI::bake_begin_function = bake_func_begin; | 
					
						
							|  |  |  |  | 	VoxelGI::bake_step_function = bake_func_step; | 
					
						
							|  |  |  |  | 	VoxelGI::bake_end_function = bake_func_end; | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 19:47:26 -03:00
										 |  |  |  | VoxelGIEditorPlugin::~VoxelGIEditorPlugin() { | 
					
						
							| 
									
										
										
										
											2016-12-23 00:37:38 -03:00
										 |  |  |  | } |