Took me a while to realize that tying this to a certain hardcoded field
isn't a good idea. The new variant is useful also for example for
getting absolute light positions or just whatever else. Besides taking a
SceneField there's now also an overload taking a field ID to avoid
double lookups. The only behavioral difference compared to the old API
is that the field is now required to exist, instead of the API being a
silent no-op if not present.
Eventually these APIs may get further extended to take a BitArrayView of
objects for which to calculate the transforms, for example to take only
meshes that are a part of the hierarchy, or meshes that satisfy an
arbitrary other condition. Which will also resolve the remaining
concerns with the API. I'm still keeping it marked as experimental tho,
the usefulness isn't set in stone yet.
The old APIs are marked as deprecated and implemented using the new
ones.
It's included in the MagnumGL library because it shouldn't be compiled
if MAGNUM_TARGET_GL is disabled. So, in other words, this was breaking
the GL-less build.
This means I (and people making their own plugins) don't need to go and
update each and every plugin once the version in the interface string
gets bumped after a (silent) ABI break. Such as when new virtual
functions get added, as those often lead to strange crashes if the
plugins don't get rebuilt after.
The plugins will now use this macro, which means they'll
automatically embed an interface string that was present in the base
class header at build time. However, when the base class updates, the
previous string is still embedded in the plugin binary, which will then
fail to load -- this being automatic doesn't mean the original purpose
is lost. Subsequently rebuilding the plugins from source will make them
pick up the updated interface string again.
The article this API was originally based on assumes a scenario which
just *isn't* matching usual practices here, giving wrong results. Too
bad I didn't spend more time questioning the proof there and just
blindly assumed it's correct because everyone said so.
Won't be typing all that reasoning again in the commit message, see the
changelog entry and the comment in the test for details.
Taking Animation::TrackViewStorage wasn't really a good idea, as it
wasn't solving anything -- in order to create it, there needs to be a
TrackView of a concrete type first anyway, and even then it required a
lot of additional verbose typing.
The new constructors take basically what TrackView takes, plus there's
additionally a constructor that takes a typeless value view together
with explicitly specified value and result types, allowing a truly
type-erased usage. On the other hand, the templated variants directly
deduce the types without any additional typing, making the construction
similarly straightforward to e.g. SceneFieldData.
In case of the type-erased constructors, if the interpolator function
isn't supplied explicitly, an implicit one is picked based on the value
type, result type and interpolation. Not all combinations make sense of
course, so this is a new assertion point, however compared to the
previous way where the interpolator was picked from a *typed* TrackView,
this doesn't add any new restriction -- what asserted there, asserts now
as well, and additionally you can't have e.g. a Quaternion track with a
boolean result. I may also be eventually adding assertions to check that
the target name matches the result type -- so e.g. a rotation isn't
specified as an integer and such. Compared to newer APIs like MeshData,
MaterialData or SceneData the AnimationData API has a significant lack
of sanity asserts like this.
The `Type` was suggesting it'd be some C++ type, definitely not values
like Scaling3D or Translation2D, resulting in a significant "brain
autocompletion error" every time I was using that type.
Unfortunately on AnimationData the trackTargetType() couldn't similarly
get renamed to trackTarget() as there's already trackTarget() that
contains the node ID the target points to, so it's trackTargetName()
instead. Renaming trackTarget() to trackTargetId() wasn't an option as
that would be inconsistent with everything else (TextureTools::image(),
MaterialAttribute::BaseColorTexture, SceneField::Mesh are all IDs but
they don't have an `Id` suffix); renaming to AnimationTrackTargetName
would keep it insanely long and wouldn't make it consistent either
(MeshAttribute, SceneFIeld, MaterialAttribute are all referred to as
"names" yet they don't have a `Name` suffix).
So it has 32k values for custom targets, instead of just 127. This
makes it consistent with MeshAttribute, which also provides 32k values,
while SceneField has a whole 31-bit range to make it possible to store
arbitrary ECS identifiers as well.
Since this is an ABI break, I'm also shifting the values by 1 to have
zero used for an invalid value, consistently with SceneField,
MeshAttribute etc.
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.
The shader requires the input data to be laid out in a rather specific
way, and there will be a dedicated MeshTools utility for it in the
following commits. For independence though, the shader tests use a
custom helper.
The initial implementation has certain corner cases which will be
eventually resolved. For now they are pinned down with repro cases in
the test. But apart from that, it's pretty much usable in practice.
Remaining join styles (round and miter-clip) as well as stipple support
will eventually follow as well.
To perform conversion of an already-indexed TriangleStrip to Triangles,
for example, without having to perform an expensive deindexing using
duplicate() first.
To be consistent with what the generate*Indices() APIs expect -- it
doesn't make sense for this API to silently round down while the other
would fail for the same input. In particular, the primitiveCount() may
be used to calculate allocation size for an array to pass to
generate*IndicesInto(), and thus it should use the same rules.
The restriction didn't make sense. Disallowing 1 input vertex for lines
or 1/2 input vertices for triangles sure, but 0 vertices should work as
the expected behavior is obvious.
The GL::Renderer::setClearDepth() and setDepthRange() APIs now use the
non-clamping NV entrypoints if available. The float overloads do that
too, to avoid differences in behavior depending on whether these
functions are called with a float or a double type.
I need alpha to coverage for rendering line caps with MSAA, took it as
an opportunity to expose the other related features as well. Fun how I
survived 12+ years without needing those.
"Funny" how this is the only API where I can't use glCreateTextures().
Like, it would have been so easy to just stop teaching glGen*() and
all their quirks and "this ID exists but it's not an object until you
bind it somewhere actually" to people altogether, BUT NO! FFS.
To match ARB_texture_view from from GL 4.3. Not sure why there's two of
them -- I was looking into the spec files, and the EXT variant seems to
be based on the OES variant but doesn't seem to add any change (or, no
change is listed), however the OES variant has number 218 while EXT has
185 so it's actually newer?! No idea what's happening there.
THe remaining elements are zero-filled, consistently with the behavior
with zeroing out attributes that are missing in subsequent meshes. One
use case is concatenating a mesh with 4 JointIds / Weights into a mesh
that has 8 instead.
Right now, copying larger arrays to smaller arrays is still disallowed
to avoid data loss. That is inconsistent with behavior for attributes
(which are silently left out when not present in the first mesh), I'll
need to think about this more and solve the inconsistency somehow.
Either by allowing array slicing or by failing for unhandled attributes
as well, and the latter makes more sense from the perspective of
avoiding data loss.
Every time I think all std::initializer_list APIs already have an
ArrayView counterpart I discover a new one. (And yes, I did this for
Framebuffer, only to later realize that DefaultFramebuffer suffers from
the same.)
Having code snippets in docs compiled and checked for syntax and
outdated API errors is great. In theory. In practice the people reading
docs have NO IDEA how much needless suffering goes into making the
compiler collaborate with me on such a seemingly simple task. UGH.
Counterparts to the sRGB-converting APIs, for when one doesn't want to
perform sRGB conversion. Or for "wrong sRGB" workflows. Named like this
and not just `fromRgbInt()` to make the calls at least a bit suspicious.
The glTF importer plugin contains functionality that's present only in
deprecated builds (backwards compatibility for skinning mesh
attributes), which isn't causing any API signature difference but rather
a difference in behavior. So expand the docs to say it's not limited to
just APIs but features in general.