-
Notifications
You must be signed in to change notification settings - Fork 59
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
AssimpImporter: import unrecognized materials + compatibility with 5.1.1 #116
Conversation
Comparing for equality used to be fine, since aiProcess_SortByPType made sure that only one flag was ever set. But assimp 5.1.0 now always sets a new aiPrimitiveType_NGONEncodingFlag for triangulated meshes, leading to an "unsupported aiPrimitiveType" error.
This needs minor changes to TinyGltfImporter test files, coming in the next commit. The last remaining failing test is an Assimp bug, fix follows in another commit. We'll ignore 5.1.0 since there are only a few days in between and it's not worth special-casing the Collada light test because of this.
Assimp's glTF importer needs a default scene to load a file at all, and cameras need to be referenced by nodes to be imported
This got broken sometime after 5.1.0. Similarly to glTF mTicksPerSecond patching, this emits a warning if detected.
Largely taken from mosra#91 Anything unrecognized is imported with the raw Assimp name and type. Can be turned off with ignoreUnrecognizedMaterialData, or overridden to import everything raw with forceRawMaterialData. The latter implies ignoreUnrecognizedMaterialData=false. For existing material tests we use ignoreUnrecognizedMaterialData, otherwise they'll break with every new Assimp version. TODO: tests, docs
Not too sure about the bool because converting from a buffer kinda defies the definition of "raw"
Just a few things I stumbled upon while working on this
This seems to be needed in project scope, even if we inject enable_language(C) into the project that's being try_compile'd
I ran into one issue I hadn't considered, and one reason CI is failing: The There's a somewhat decent alternative: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, as always 👍
There's one commit marked as [wip]
, is it still WIP or just a stale message?
the 5.0.1 code confirms that no importer sets attributes | ||
starting uppercase, so an assert should be fine here. | ||
Revisit if this breaks for someone. */ | ||
/** @todo $ conflicts with Magnum's material layer names */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sigh, I didn't fix this yet? 😅
@@ -70,6 +70,8 @@ endif() | |||
# temporary CMakeList.txt created by try_compile: | |||
# https://github.com/Kitware/CMake/blob/v3.4.0/Source/cmCoreTryCompile.cxx#L313 | |||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/checkAssimpVersionLanguageOverride.cmake "enable_language(C)") | |||
# For some reason, this also needs C to be enabled in this scope | |||
enable_language(C) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sigh. Gotta admit I don't like this part at all :/ I'm wondering if I could expand the above static library workaround to not need to link to the assimp
target ever, sidestepping the problem with a C99 feature enabled on it.
Would defining our own alternative enum directly in the plugin source work? This of course assumes the IDs don't change across Assimp versions. What I want to still have, however, is GCC/Clang notifying me if a new Assimp version adds more values to the enum... but according to my testing, this should work: enum class AssimpTextureType { // alternative naming
...
CLEARCOAT = 20,
TRANSMISSION = 21,
...
};
switch(semantic) { // `semantic` is still an aiTextureType to make GCC/Clang check for unhandled values
...
case aiTextureType(int(AssimpTextureType::CLEARCOAT)): // cast so it doesn't warn about mismatched types
...
}
I'm a bit on the fence about this -- the UPPER_CASE is what people are used to from the Assimp API, so I guess the name should match what the aiTextureType has? Another reason is that if people see some weird unexpected texture name in there, they could then directly grep for that string in Assimp sources and get angry immediately. But if it would be translated to CamelCase then they can't. |
And test that it works with the PBR texture types added in 5.0.0
5eb6b21
to
63a48e7
Compare
AI_MATKEY_TRANSPARENCYFACTOR only got added in 4.0.0. We're already testing other float attributes so we don't need to test this one, and there isn't really any good replacement that's universally supported
It compiles, now we enter the cursed bugs phase 😬
Remaining issues:
|
Yay bugs! 🤩
This one is funny! The code checking this is https://github.com/mosra/magnum/blob/f51110fe9847c63953aec382b90fb4ab24022133/src/Magnum/Trade/MaterialData.cpp#L233-L240 and I see two possibilities:
Very funny also!! I Clearly a garbage in the upper 32 bits for some reason. I remember there's a Actually, WHAT THE FUCK, it seems that I also see things in the CI log like
Sorry, the job is named misleadingly -- it disables deprecated APIs and also all asserts. So then the string view size assert doesn't fire because it doesn't exist. (I optimized for CI turnaround time and this seemed like an acceptable tradeoff.)
There's this very amazing and stroke-inducingly funny way of how Assimp assigns cameras and lights to nodes. It just makes the name of both the same, which then you discover by going through all cameras and all nodes for every node. Very quadratic. It also says that "there can be multiple cameras with the same name, which means given node has all those cameras assigned" even though I was never able to reproduce that, so I guess this was "technically" why back then a camera inherited the name from its node and not the other way around, but then somebody complained that this sucks and so it got inverted?
I guess some XFAIL / SKIP could do here? The Mac and Windows CIs test this thoroughly enough, so if the ancient Ubuntu won't test a few cases it's fine.
Huh... you mean, when you have Assimp as a subproject? Or external? For external libraries I only copy DLLs of SDL and GLFW, nothing else. So if it's doing this, then it has to be some automagic out of my reach. |
That's some impressive detective work 😱 Thanks for the quick fix!
It gets even funnier,
Sorry for not clarifying, yeah, I meant subprojects. I tracked it down to these commits: assimp/assimp@be4fe13 Assimp used to set |
❤️ 🔥 I'm speechless.
This was never expected to have any impact on subprojects (which is why I'm doing explicit handling for GLFW and SDL DLLs). Usually I build plugin dependencies as static, so the dynamic module is self-contained. That would "fix" this issue I think ... or do you need a dynamic build because the test uses Assimp APIs as well? Or ... is it possible the suggested CMake snippet in the docs (where it forces a static build) doesn't work anymore and you get a DLL? |
Assimp 3.2 takes camera names from the node that they're attached to
My personal new favorite assimp bug: aiString::length is a size_t before version 5, but the material property functions dealing with strings decided to store them as a uin32_t directly followed by the string content. aiString::C_Str() however doesn't know about those hacks, so when you interpret the material property data as an aiString directly, this blows up in your face with parts of the string data being read as the length. The solution is to use the getter function, which leads to a copy. Alternatively I could have replicated the internal layout but it's enough if Assimp performs these atrocities. Any poor soul using prehistoric versions of this library has far more to worry about than an extra string copy.
And import them as a typeless buffer, since we have that functionality already. Currently untested.
Layered FBX materials are not supported, and skipping around indices in materialRawUnrecognized() would be too awkward. Should be enough to test this on 5.0.0 and up
Heh, good to know. I thought this was intended, because things just magically worked with 5.0.1 even without forcing |
My brain slipped while writing that one commit message 👀 When you merge and rebase, can you change it to: The new Linux build failures in |
Oh no, now cursed old Clang bugs 🙈 |
Seems like the root cause is that Clang 3.8 treats C arrays as not trivially copyable for some reason, and the code in question uses a multi-dimensional array, so the static_assert happens on a type that's still an array and 💥 But it worked before (picking some other overload) so I'll just disable the new feature of copying to C arrays from mosra/corrade@dc173b4 for multi-dimensional arrays on Clang 3.8. |
Homebrew apparently has bottles for 5.1.2 already, so we could probably upgrade to that on the Mac CI |
Codecov Report
@@ Coverage Diff @@
## master #116 +/- ##
==========================================
+ Coverage 94.86% 95.42% +0.55%
==========================================
Files 115 115
Lines 9484 10510 +1026
==========================================
+ Hits 8997 10029 +1032
+ Misses 487 481 -6
Continue to review full report at Codecov.
|
Unfortunately that would mean increasing macOS build times by 10 minutes (because yes of course, |
Merged as d676a6b...5329b00. I squashed some commits together to always have code+docs+tests in a single commit, but other than that it's mostly following your original sequence. I tried to figure out some alternative to The Thank you!! |
👋 It is finally finished
This PR does a few things:
Raw material import
I took the raw material import from #91, fixed a few things and added tests. AssimpImporter now imports unrecognized material properties with their raw names and types. If a type is unsupported, it gets exported as an opaque buffer inside
MaterialAttributeType::String
. This default behaviour can be turned off with theignoreUnrecognizedMaterialData
option.If this behaviour is always wanted, the
forceRawMaterialData
option has you covered. That last one is only really useful for tests I suppose.There is some rudimentary documentation, but that could probably be extended a bit.
Compatibility with 5.1.1
As always, this new version of assimp broke a dozen things. It's kind of what happens when for two years, every PR gets insta-merged with no useful code review or tests, and obviously nobody uses this rickety library on latest master. Non-exhaustive list of disappointments:
scene
property, which is of course not mandatory in the glTF specI don't know if these are worth documenting. Let me know what you consider important. Cataloguing every single assimp bug in the docs makes me shudder.
Missing data
A few things were not previously imported, either because they were forgotten, or because they were added in a newer version of assimp or magnum. These things are now imported:
LightData::Type::Ambient
, notPoint