It's needed to support the new material attributes supported by glTF.
The test output is slightly different as the normal coming from
the texture wasn't normalized before.
Interestingly enough / sadly none of the tests showed a clear difference
when removing the incorrect normalization, so here's a dedicated test
case. Sigh.
Makes more sense as the function isn't expected to fail (and thus any
kind of lazy population is not possible as it would be too late for
error checks anyway).
*Not* updating interface strings even though this is an ABI break
because we're doing that right after the skin import interface bump.
THe new MaterialData APIs introduce MaterialAttributeType::Bool and
everything kinda explodes with that.
Seriously, what were the people in 1979 thinking.
The new materials now commonly import separate per-texture matrices
instead of a single one even if they're all the same because that makes
the plugin implementation *much* simpler. However, existing code that
assumes there's just one matrix would get broken because textureMatrix()
would not return something else. By changing that to return a common
matrix if present and falling back to the global one we can preserve the
original behavior.
There's actually a lot of code involved in checking if all textures use
the same transform or coordinate set, especially when considering all
fallback variants and potential future expansion with separate texture
offset/scale/rotation attributes.
A lot of the complexity was thus hidden in plugin implementations, which
were each trying to find a common value for all textures to save the
user from doing the same. All that code can now be removed and left up
to the material APIs themselves -- now it's just about checking
hasCommonTextureTransformation() and then retrieving that one common
transformation, independently on how the material actually defines it.
Turns out glTF doesn't actually put metalness into R and roughness into
G, even though the naming suggests that. This was done originally, but
then they changed that in order to be compatible with UE4 and allow for
a more efficient storage of an occlusion map.
Because this feels extremely arbitrary, the docs have added rationale
for each of the packing variants, and I'm also renaming the packed
attribute and checks to imply the red channel isn't used.