Some (poorly authored) glTF assets have several `image` elements
that all refer to the same URL or buffer view. When this occurs,
we create only 1 Filament Texture.
These assets regressed after PR 6051, which consolidated the texture
related fields in `FilamentAsset`, but did not include an ownership flag
in the new `TextureInfo` struct.
The asset previously had three confusing fields related to textures:
mTextures, mTextureSlots, and mTextureBindings.
These are now consolidated into a single field, which simply has one top
level array item per `cgltf_texture`.
The memory footprint is smaller because we no longer bother to store
`TextureSampler` objects, instead we simply defer their construction
until calling setParameter.
Last but not least, we now assert in debug builds if the usages of a
particular texture have inconsistent sRGB flags. In the past,
inconsistent sRGB would be silently ignored.
In other words, we will now assert if you try to use the same texture
for `baseColor` and `normalMap`, whereas in the past we would simply
exhibit non-deterministic behavior in this situation (with respect to
sRGB semantics).
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.
Bug was introduced with de7dfc2ea6.
I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
For each "cgltf_material", we now create one "MaterialInstance", even
if a given asset has multiple instances. In the future, we might make
this behavior configurable to make better use of Filament's
auto-instancing feature.
This change is a feature request from Google, but also this behavior is
more consistent with the code comments.
Also some related cleanup:
(1) Use FixedCapacityVector instead of robin_map.
(2) Move the cache to move out of the asset and into the loader,
because it is only used at load time.
This change was motivated by some internal work at Google and has the
benefit of simplifying the gltfio API and implementation. There are 2
major API changes:
(1) Consolidate separate loader entry points for GLB and GLTF.
The distinction between GLB and GLTF can be made from the file content
alone, because GLB has a 4-byte magic string in its header. There is no
need for separate entry points. Clients do not (and should not) need
to check the file name extension.
(2) Remove the distinction between "instanced" and "non-instanced"
glTF assets.
In the new scheme, all assets have at least 1 instance.
Broadly speaking, in gltfio an "asset" is a collection of Filament
objects like textures and vertex buffers, while an "instance" is a
collection of entities and components (e.g. the transform hierarchy).
This API change makes life easier for clients because they no longer
need to decide a priori if they will ever need to add instances.
This change also moves some public-facing methods from FilamentAsset to
FilamentInstance:
- getSkinCount, getSkinNameAt
- getJointCountAt, getJointsAt
- attachSkin, detachSkin
* Add multi-scene support to gltf_viewer.
To test this, I generated a multi-scene asset as follows.
```
gltf-transform merge Avocado/glTF/Avocado.gltf \
BarramundiFish/glTF/BarramundiFish.gltf \
~/Desktop/Merged.gltf
```
* Specify c++17 in pbxproj files.
- For completion, FilamentAsset now has getRenderableEntities(). This is
similar to sister methods getLightEntities() and getCameraEntities()
except there is no need to store a separate array.
- The web helmet demo does not need to enable shadows, they are already
enabled.
- The ViewerGui populateAsset() method was doing two things that are
now decoupled for clarity: setAsset() and populateAsset().
- The updateRootTransform() method is now called only when the autoscale
checkbox is toggled, instead of every frame.
- The getFooEntities() methods in Java now skip doing work for empty
lists. Actually these should not return arrays at all, but let's fix
that later, since it will break backwards compatibility.
In the past there was an API gotcha because users had to "get" the
animator before releasing the glTF source data. This could have been
surprising because it was a getter method, not a factory method.
This was due to overeager optimization on my part, I wanted to avoid
animator overhead for non-animated models, when in fact it has very
little overhead.
Moreover, the animator is conceivably useful even when there are no
pre-supplied animations (e.g. for applying skins), so let's just create
it unconditionally.
Motivated by #5299.
* Get the morph target count from the renderable
* Set the morph target count by Builder
* Update morph target weights partially
* Remove noexcept at functions could throw exceptions
* Update Java bindings at RenderableManager
* Add missing comments
* Update morph target weights from offset
Co-authored-by: Mathias Agopian <mathias@google.com>
This allows clients to obtain the extras strings for the asset and
for individual nodes. Note that extras for buffer views, accessors, etc
are not supported, although C++ clients can access the raw cgltf data
directly if they need to.
The gltfio API allows users to destroy ResourceLoader or FilamentAsset
even when various asynchronous work (e.g. uploading buffers to the GPU)
has not yet been completed. This was achieved in an error-prone manner
using manual reference counting and an internal management object called
AssetPool.
This PR refactors gltfio by wrapping cgltf_data in shared_ptr, which I
usually try to avoid. However in this case it provides the precisely the
functionality that is needed.
I tested this PR for memory leaks and crashes by hacking gltf_viewer
and monitoring memory usage in Activity Monitor.
This fixes#3383 and makes it easier to implement some missing features,
such as animation support for instanced assets.
This prepares for #3137 by moving the mesh cache and material instance
cache out of the loader (where they were transient anyway) and into the
actual asset. This paves the way for a `createInstance()` API.
This feature adds one new method to `FilamentAsset` and uses it in our
Kotlin, JavaScript, and C++ helpers:
utils::Entity popRenderable() noexcept;
This pops a ready renderable off an internal queue, or returns 0 if no
renderables have become ready. It provides a simple way for clients to
gradually add renderables to the scene as they become ready. Previously
clients could only get the entire list of entities, regardless of
whether they had Renderable components or complete textures.
To facilitate this feature, this PR adds a new internal-only class to
gltfio called `DependencyGraph`, which is a temporary object used for
bookkeeping during the asynchronous load.
`DependencyGraph` discovers ready-to-render entities by tracking the
textures that each entity depends on. This is a graph because
renderables connect to a set of material instances, which in turn
connect to a set of parameter names, which in turn connect to a set of
texture objects. These relationships are not easily inspectable using
the Filament API or ECS.
Some buffers (like animation data) do not contain any vertex data
but web-based clients still need to know about this.
This interface is much simpler than the bindings lists, and in fact
we might remove the binding lists in the future to simplify the API.
Fixes#1593.
This makes it easy to draw a transformed box around each renderable for
diagnostic purposes. The API is similar to Animator in that it is
exposed through FilamentAsset but is created lazily and is implementated
outside of FilamentAsset.
This is our new mobile-friendly and web-friendly library for loading
glTF assets. It is still a work in progress, but already capable of
loading many conformance models, including those with animation,
skinning, and a couple of extensions (nonlit and texture transforms).
Next week we will add a sample app demonstrating its usage.