Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLTF: Don't give up loading a texture if importing it fails #96778

Merged
merged 2 commits into from
Nov 5, 2024

Conversation

aaronfranke
Copy link
Member

This fix is needed for #82455, but this PR does not completely solve that issue.

In the current master, if in the editor and the import settings are set to extract textures (default), the code in GLTFDocument will fail if it cannot extract and import a texture, resulting in that texture being missing from the model.

This PR is a fairly straightforward change: If we can't import, just load it uncompressed from the Image resource already loaded in memory, instead of giving up and inserting a blank texture.

More details: For each case where the image cannot be imported from res://, instead of setting a blank texture, use the loaded image. The return in this function now only happens after successful cases, so as a fallback, it will drop down to the bottom of the function, the uncompressed code. This is the same as if performing a runtime import. When writing this code I was curious if it would work if the project is exported, and actually yes, it does work.

As a bonus, I also added some text to two err_fail_conds in EditorFileSystem to make them distinct from each other.

@lyuma
Copy link
Contributor

lyuma commented Oct 3, 2024

In my opinion p_state->base_path.is_empty() case should assign a name (such as a number) and extract it, not load it uncompressed.

this should be the same as a glb file with embedded unnamed textures, which also should get extracted.

@aaronfranke aaronfranke force-pushed the gltf-dont-fail-import branch from 4bf3865 to d1d2646 Compare October 3, 2024 22:24
@aaronfranke
Copy link
Member Author

aaronfranke commented Oct 3, 2024

@lyuma I'm assuming you mean the p_image->get_name().is_empty() condition. If the base path is empty, we can't extract, because we have nowhere to save it. I've updated the PR. Old PR code:

if (p_state->base_path.is_empty()) {
	WARN_PRINT("glTF: Couldn't extract image because the base path is empty. It will be loaded directly instead, uncompressed.");
} else if (p_image->get_name().is_empty()) {
	WARN_PRINT(vformat("glTF: Image index '%d' couldn't be named. This cannot be saved to a file. It will be loaded directly instead, uncompressed.", p_index));
} else {
	bool must_import = true;
	// and so on

Code in this PR with your suggestion:

if (p_state->base_path.is_empty()) {
	WARN_PRINT("glTF: Couldn't extract image because the base path is empty. It will be loaded directly instead, uncompressed.");
} else {
	if (p_image->get_name().is_empty()) {
		WARN_PRINT(vformat("glTF: Image index '%d' did not have a name. It will be automatically given a name based on its index.", p_index));
		p_image->set_name(itos(p_index));
	}
	bool must_import = true;
	// and so on

Note that this is technically a separate issue, but it's the same part of the code, so I'm personally good with fixing 2 issues with one PR as long as that's good with you.

@aaronfranke aaronfranke force-pushed the gltf-dont-fail-import branch from d1d2646 to 3d73659 Compare October 30, 2024 07:31
@aaronfranke aaronfranke requested a review from a team as a code owner October 30, 2024 07:31
@aaronfranke aaronfranke force-pushed the gltf-dont-fail-import branch 2 times, most recently from ea38726 to 13c42c3 Compare October 30, 2024 10:01
@aaronfranke
Copy link
Member Author

Updated the PR to have a second commit which adds extract_path and extract_prefix settings, used by the Blender importer. This allows textures extracted from the glTF file to be placed next to the .blend file, as suggested by @lyuma in Discord messages.

Copy link
Contributor

@lyuma lyuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! A good combination of additional error checking and bugfixes.

Copy link
Contributor

@Repiteo Repiteo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitpicks, but otherwise looks good

editor/editor_file_system.cpp Outdated Show resolved Hide resolved
editor/editor_file_system.cpp Outdated Show resolved Hide resolved
@aaronfranke aaronfranke force-pushed the gltf-dont-fail-import branch from 75c8b98 to 5ee1484 Compare November 5, 2024 01:57
@aaronfranke aaronfranke force-pushed the gltf-dont-fail-import branch from 5ee1484 to 02d8c6e Compare November 5, 2024 03:29
@Repiteo Repiteo merged commit e38068f into godotengine:master Nov 5, 2024
19 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Nov 5, 2024

Thanks!

@aaronfranke aaronfranke deleted the gltf-dont-fail-import branch November 5, 2024 12:00
@demolke
Copy link
Contributor

demolke commented Nov 5, 2024

This has a surprising (at least to me) side effect - if you're not using embedded textures in blend files your textures will get duplicated.

model.blend pointing to on-disk texture.png will also create model_texture.png

Is that working as intended?

It feels like there are three options

  • gltf with embedded images -> should be saved to disk
  • gltf pointing to textures within res:// directory -> should be skipped
  • gltf pointing to textures outside res:// directory -> should be saved to disk

@aaronfranke
Copy link
Member Author

@demolke True. If needed, we can revert the second commit in this PR, which will instead load the image directly instead of importing it in this case. However, I think really this is highlighting an existing problem - wouldn't this mean that a non-embedded texture from a Blend file isn't being used? How can we detect and use these textures?

@demolke
Copy link
Contributor

demolke commented Nov 6, 2024

wouldn't this mean that a non-embedded texture from a Blend file isn't being used? How can we detect and use these textures?

I'm not sure what you mean - I only went through the code superficially so don't see how it detects if the original texture.png is already imported/used. The part with md5 only checks for the prefixed model_texture.png.import so that will not help with de-duplication.

This project shows that after import you will get model_texture.png even though texture.png has already been imported
nonembed.zip

demolke added a commit to demolke/godot that referenced this pull request Nov 6, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
@demolke
Copy link
Contributor

demolke commented Nov 6, 2024

I spent some time poking at this and I think this #98909 addresses most of the use cases

demolke added a commit to demolke/godot that referenced this pull request Nov 7, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 7, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 7, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 7, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 11, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 12, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 13, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
demolke added a commit to demolke/godot that referenced this pull request Nov 14, 2024
blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures.

Introduce a new state where the resource exists on the disk but has not been imported yet.GLTF: Don't duplicate textures when importing blend files

blender imports will always start with `.godot/imported` because we first convert the blend to gltf, store it in `.godot/imported` and run the import from there, so resources linked from blend files end up with duplicate textures after godotengine#96778

Introduce a new state where the resource exists on the disk but has not been imported yet.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants