Browse Source

Disable navmesh, lightmap, and VoxelGI generation on foreign data

SaracenOne 3 years ago
parent
commit
f5edeb8f58

+ 12 - 6
doc/classes/LightmapGI.xml

@@ -93,22 +93,28 @@
 		<constant name="BAKE_ERROR_OK" value="0" enum="BakeError">
 			Lightmap baking was successful.
 		</constant>
-		<constant name="BAKE_ERROR_NO_LIGHTMAPPER" value="1" enum="BakeError">
+		<constant name="BAKE_ERROR_NO_SCENE_ROOT" value="1" enum="BakeError">
+			Lightmap baking failed because the root node for the edited scene could not be accessed.
+		</constant>
+		<constant name="BAKE_ERROR_FOREIGN_DATA" value="2" enum="BakeError">
+			Lightmap baking failed as the lightmap data resource is embedded in a foreign resource.
+		</constant>
+		<constant name="BAKE_ERROR_NO_LIGHTMAPPER" value="3" enum="BakeError">
 			Lightmap baking failed as there is no lightmapper available in this Godot build.
 		</constant>
-		<constant name="BAKE_ERROR_NO_SAVE_PATH" value="2" enum="BakeError">
+		<constant name="BAKE_ERROR_NO_SAVE_PATH" value="4" enum="BakeError">
 			Lightmap baking failed as the [LightmapGIData] save path isn't configured in the resource.
 		</constant>
-		<constant name="BAKE_ERROR_NO_MESHES" value="3" enum="BakeError">
+		<constant name="BAKE_ERROR_NO_MESHES" value="5" enum="BakeError">
 			Lightmap baking failed as there are no meshes whose [member GeometryInstance3D.gi_mode] is [constant GeometryInstance3D.GI_MODE_STATIC] and with valid UV2 mapping in the current scene. You may need to select 3D scenes in the Import dock and change their global illumination mode accordingly.
 		</constant>
-		<constant name="BAKE_ERROR_MESHES_INVALID" value="4" enum="BakeError">
+		<constant name="BAKE_ERROR_MESHES_INVALID" value="6" enum="BakeError">
 			Lightmap baking failed as the lightmapper failed to analyze some of the meshes marked as static for baking.
 		</constant>
-		<constant name="BAKE_ERROR_CANT_CREATE_IMAGE" value="5" enum="BakeError">
+		<constant name="BAKE_ERROR_CANT_CREATE_IMAGE" value="7" enum="BakeError">
 			Lightmap baking failed as the resulting image couldn't be saved or imported by Godot after it was saved.
 		</constant>
-		<constant name="BAKE_ERROR_USER_ABORTED" value="6" enum="BakeError">
+		<constant name="BAKE_ERROR_USER_ABORTED" value="8" enum="BakeError">
 			The user aborted the lightmap baking operation (typically by clicking the [b]Cancel[/b] button in the progress dialog).
 		</constant>
 		<constant name="ENVIRONMENT_MODE_DISABLED" value="0" enum="EnvironmentMode">

+ 46 - 10
editor/plugins/lightmap_gi_editor_plugin.cpp

@@ -35,12 +35,43 @@
 
 void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
 	if (lightmap) {
-		LightmapGI::BakeError err;
+		LightmapGI::BakeError err = LightmapGI::BAKE_ERROR_OK;
 		const uint64_t time_started = OS::get_singleton()->get_ticks_msec();
-		if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) {
-			err = lightmap->bake(lightmap, p_file, bake_func_step);
+		if (get_tree()->get_edited_scene_root()) {
+			Ref<LightmapGIData> lightmapGIData = lightmap->get_light_data();
+
+			if (lightmapGIData.is_valid()) {
+				String path = lightmapGIData->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) {
+								err = LightmapGI::BAKE_ERROR_FOREIGN_DATA;
+							}
+						} else {
+							if (FileAccess::exists(base + ".import")) {
+								err = LightmapGI::BAKE_ERROR_FOREIGN_DATA;
+							}
+						}
+					}
+				} else {
+					if (FileAccess::exists(path + ".import")) {
+						err = LightmapGI::BAKE_ERROR_FOREIGN_DATA;
+					}
+				}
+			}
+
+			if (err == LightmapGI::BAKE_ERROR_OK) {
+				if (get_tree()->get_edited_scene_root() == lightmap) {
+					err = lightmap->bake(lightmap, p_file, bake_func_step);
+				} else {
+					err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step);
+				}
+			}
 		} else {
-			err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step);
+			err = LightmapGI::BAKE_ERROR_NO_SCENE_ROOT;
 		}
 
 		bake_func_end(time_started);
@@ -59,16 +90,21 @@ void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
 
 				file_dialog->set_current_path(scene_path);
 				file_dialog->popup_file_dialog();
-
 			} break;
-			case LightmapGI::BAKE_ERROR_NO_MESHES:
+			case LightmapGI::BAKE_ERROR_NO_MESHES: {
 				EditorNode::get_singleton()->show_warning(TTR("No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake Light' flag is on."));
-				break;
-			case LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE:
+			} break;
+			case LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE: {
 				EditorNode::get_singleton()->show_warning(TTR("Failed creating lightmap images, make sure path is writable."));
-				break;
+			} break;
+			case LightmapGI::BAKE_ERROR_NO_SCENE_ROOT: {
+				EditorNode::get_singleton()->show_warning(TTR("No editor scene root found."));
+			} break;
+			case LightmapGI::BAKE_ERROR_FOREIGN_DATA: {
+				EditorNode::get_singleton()->show_warning(TTR("Lightmap data is not local to the scene."));
+			} break;
 			default: {
-			}
+			} break;
 		}
 	}
 }

+ 28 - 1
editor/plugins/voxel_gi_editor_plugin.cpp

@@ -35,7 +35,9 @@
 
 void VoxelGIEditorPlugin::_bake() {
 	if (voxel_gi) {
-		if (voxel_gi->get_probe_data().is_null()) {
+		Ref<VoxelGIData> voxel_gi_data = voxel_gi->get_probe_data();
+
+		if (voxel_gi_data.is_null()) {
 			String path = get_tree()->get_edited_scene_root()->get_scene_file_path();
 			if (path.is_empty()) {
 				path = "res://" + voxel_gi->get_name() + "_data.res";
@@ -46,7 +48,32 @@ void VoxelGIEditorPlugin::_bake() {
 			probe_file->set_current_path(path);
 			probe_file->popup_file_dialog();
 			return;
+		} 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;
+				}
+			}
 		}
+
 		voxel_gi->bake();
 	}
 }

+ 29 - 1
modules/navigation/editor/navigation_mesh_editor_plugin.cpp

@@ -60,12 +60,40 @@ void NavigationMeshEditor::_bake_pressed() {
 	button_bake->set_pressed(false);
 
 	ERR_FAIL_COND(!node);
-	if (!node->get_navigation_mesh().is_valid()) {
+	Ref<NavigationMesh> navmesh = node->get_navigation_mesh();
+	if (!navmesh.is_valid()) {
 		err_dialog->set_text(TTR("A NavigationMesh resource must be set or created for this node to work."));
 		err_dialog->popup_centered();
 		return;
 	}
 
+	String path = navmesh->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) {
+					err_dialog->set_text(TTR("Cannot generate navigation mesh because it does not belong to the edited scene. Make it unique first."));
+					err_dialog->popup_centered();
+					return;
+				}
+			} else {
+				if (FileAccess::exists(base + ".import")) {
+					err_dialog->set_text(TTR("Cannot generate navigation mesh because it belongs to a resource which was imported."));
+					err_dialog->popup_centered();
+					return;
+				}
+			}
+		}
+	} else {
+		if (FileAccess::exists(path + ".import")) {
+			err_dialog->set_text(TTR("Cannot generate navigation mesh because the resource was imported from another type."));
+			err_dialog->popup_centered();
+			return;
+		}
+	}
+
 	NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
 	NavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node);
 

+ 2 - 0
scene/3d/lightmap_gi.cpp

@@ -1538,6 +1538,8 @@ void LightmapGI::_bind_methods() {
 	BIND_ENUM_CONSTANT(GENERATE_PROBES_SUBDIV_32);
 
 	BIND_ENUM_CONSTANT(BAKE_ERROR_OK);
+	BIND_ENUM_CONSTANT(BAKE_ERROR_NO_SCENE_ROOT);
+	BIND_ENUM_CONSTANT(BAKE_ERROR_FOREIGN_DATA);
 	BIND_ENUM_CONSTANT(BAKE_ERROR_NO_LIGHTMAPPER);
 	BIND_ENUM_CONSTANT(BAKE_ERROR_NO_SAVE_PATH);
 	BIND_ENUM_CONSTANT(BAKE_ERROR_NO_MESHES);

+ 2 - 0
scene/3d/lightmap_gi.h

@@ -124,6 +124,8 @@ public:
 
 	enum BakeError {
 		BAKE_ERROR_OK,
+		BAKE_ERROR_NO_SCENE_ROOT,
+		BAKE_ERROR_FOREIGN_DATA,
 		BAKE_ERROR_NO_LIGHTMAPPER,
 		BAKE_ERROR_NO_SAVE_PATH,
 		BAKE_ERROR_NO_MESHES,