Compared to Corrade, the improvement in compile time is about a minute
cumulative across all cores, or about 8 seconds on an 8-core system (~2
minutes before, ~1:52 after). Not bad at all. And this is with a
deprecated build, the non-deprecated build is 1:48 -> 1:41.
When writing high-level documentation for those I realized that it's
easier to just add the r-value variants than trying to explain why one
has to be careful to not pass r-values there.
Sometimes it's desirable to just make a mesh indexed unconditionally,
which wasn't really possible with this thing, and having to special-case
that at the call site is very annoying. Now it makes a mesh
trivially indexed if it has any other primitive than the ones listed,
and if it's already indexed, it's just passed through.
Not that C++ STL and exceptions would be anything to take inspiration
from, but there's std::out_of_range. Python IndexError is also specified
as "index out of range", not "bounds".
Partially needed to avoid build breakages because Corrade itself
switched as well, partially because a cleanup is always good. Done
except for (STL-heavy) code that's deprecated or SceneGraph-related APIs
that are still quite full of STL as well.
With the workarounds moved to the GL::Shader class itself, it's just a
complicated wrapper for adding the compatibility.glsl file and a rather
strange way to define a file-local helper for resource import on static
builds. Do that directly instead.
While extremely easy to do with the linear lookup, I bet it'd be
something utterly complex like trying to hash a std::pair with the
original hashmap-based implementation.
Building a mesh from scratch makes the test much easier to grasp and
allows me to test more corner cases together instead of having to add
special cases for offset-only, array and implementation-specific
attributes.
The test now also uncovers a potential optimization opportunity where a
copy of the attribute metadata could be avoided in some cases. Not
implementing it right now, just adding a TODO and an XFAIL.
A bit sad it took me three years to invent the right name for this
utility, heh. Also moving it together with others to a new
MeshTools/Copy.h header because *this* is the mainly useful API, not
reference() / mutableReference().
MaterialTools and SceneTools will get similar copy() APIs doing the same
thing.
The new filterAttributes() API takes a BitArray, which makes the
internals a lot simpler -- no O(n^2) lookup, no growable arrays, and no
need to duplicate the same code in the ID- and name-based variants.
For consistency with MaterialTools and soon MeshTools, the APIs are
moved to a new Filter.h header, with the deprecated variants kept only
in the original FilterAttributes.h.
Instead of saying "which is not supported" in each assert, which is
vague and might imply that "it eventually will be supported", document
the actual reason in a single place, which is the MeshAttributeData docs.
This is unfortunately a breaking change to compileLines(), which now
takes the output of generateLines() instead of a line mesh. There's a
new assertion that'll blow up if the code is used the previous way,
sorry for the breakage.
What's however very useful about this change is that now it's possible
to take those generated line meshes and concatenate() them together,
achieving what's otherwise not implemented yet, such as drawing several
disconnected line strips or loops together.
It's all still partially private (the custom mesh attribute names are)
and I'm marking both APIs as experimental now to hint that it's not in
the final form/functionality yet. In particular, the data layout
optimizations described in the shader docs aren't used by these tools
yet, and if/once the line-specific vertex attributes become builtin,
compileLines() will not need to exist anymore as compile() will handle
that directly.
Currently just the bare minimum, more features such as handling
multiple contiguous strips and loops inside a single mesh or an
overlapping layout will come later.
Otherwise it may be hard to guess which of them is failing. *Ideally*
the assert would also contain the stride vs type size, maybe I do
that next time I spend that much time investigating why it asserts.