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.
The immutable inverse bind matrices can be shared among instances, so
they are now stored in Asset, not in Instance.
Also, there are now two "load" phases for skinning data:
(1) storing the inverse bind matrices
(2) building the Entity mappings (for animation efficiency)
Phase 1 is done in `ResourceLoader` because inverse bind matrices can
live in an external bin file.
Phase 2 is done during Instance creation, because that's when entities
are created.
Prior to this change, `recomputeBoundingBoxes` was an opt-in config
parameter in ResourceLoader. It is now a method on FilamentInstance.
The old API did not work for dynamically created instances. Since this
is a relatively obscure feature, we considered removing it completely,
especially since the computation requires the presence of CPU-side
vertex data combined with the transform hierarchy.
Instead of removing the feature, we decided to move it to a better
place. This paves the way for some upcoming improvements, which include
reducing the memory footprint for assets. It also improves overall code
organization and separation of concerns.
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
The custom release callback that I provided was in the wrong place; it
was only being used for a path string, not the actual buffer content.
The cgltf API is a bit awkward in this area.
No need to update RELEASE_NOTES because this will be cherry picked to
the RC branch, which is where the bug introduced.
Fixes#5918.
* 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.
This adds a new implementation of the TextureProvider interface called
Ktx2Provider.
Tested using the KTX2 variant of the StainedGlassLamp model in the
Khronos samples repo.
Tested on WebGL 2.0 (Chrome v100), Android (Pixel 6 Pro), and Desktop
(Metal, OpenGL, and Vulkan via MoltenVK).
We now handle "too many bone weights" in the same way that we handle
"too many UV sets". i.e. emit an error message and do not panic.
This change allows us to render the model in #5234 quite reasonably.
Fixes#5234.
* 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 fixes two bugs that combined in a way that prevented a double-free
error.
The destructor of the impl class for AssetLoader was never called, which
was sort of good, because it should not destroy the material provider.
The asset loader was never meant to have ownership over the provider.
* Add support for KHR_materials_volume
* Add ubershader support for KHR_materials_volume
* Update readmes
* User highp on anything that affects UVs
* Add missing precision qualifiers
* Fix transmission
This adds some significant JNI glue in order to make the Java API for
gltfio materials much more consistent with C++, and create feature
parity between the two languages.
The motivation is to allow Java clients to provide their own
ubershader-based solution or filamat-based solution.
- The `MaterialProvider` Java class is now an interface.
- The `UbershaderLoader` Java class is now a concrete implementation.
- Users can now write their own provider class using Java / Kotlin.
To streamline the amount of JNI work that occurs at run time, the
MaterialProvider Java interface uses ints in a couple spots instead
of enums. This sacrafices some readability for Java clients who wish
to write their own provider, but makes the JNI much simpler.
This replaces #3975.
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 code that determined the "base slot" (i.e. the buffer object index
for the first morphed attribute) was very fragile and buggy.
MorphHelper now simply looks up the slot index in a stored mapping,
rather than trying to mimic the AssetLoader to determine the base slot.
Until now, most of the models we tested against only morphed the
position attribute, and never had a large set of target weights that
could be non-zero in a given time slice.
Fixes issue seen with Vulkan + the quantized version of Avocado.
We already support the quantized glTF extension, which is when this
comes up. Technically this is only needed for Vulkan but gltfio does
not (and should not) know which backend is being used, so we simply
apply these transformations assuming the worst.
In practice this code usually won't be activated, and if even when it
is, it won't hurt loading time as much as other things like large
textures.
* gltfio: Add internal MorphHelper, enable up to 255 targets.
Previously, gltfio could not animate models with more than 4 morph
targets. Now we can handle up to 255 targets, as long as no more than
4 targets are ever used simultaneously. This allows us to handle
many more models, such as those exported by Modo, and the horse model
in #1852.
We do this by picking the highest 4 weights. The indices for these
weights are called the "primary indices", and we construct a new
VertexBuffer for each unique set of primary indices.
In the near future this will be made more efficient by adding a new
VertexBuffer API to the Filament core.
Fixes#1487.
* Code review fixups.
- Add a "shift" parameter to Camera. This has the effect of translating
the viewport, without changing its size.
This is an effect similar to using a shift lens.
- Camera::setScaling() now takes a double2 instead of double4, this is
because scaling the result of the projection in the Z direction
can lead to very confusing problems -- it will essentially move the
near/far planes, and we don't want to expose that as a public API.
- setCustomProjection() now allows to set a different projection for
rendering and culling (useful for e.g. for using an infinite far
rendering projection matrix).
MaterialGenerator selects a custom blend mode for transmissive models,
therefore the AssetLoader should look at the material's blend mode when
it sets up properties, not the one requested by the glTF file.
Fixes#3444.
I tested this by viewing CesiumMan with our `gltf_instances` sample app.
There is now a need for some general refactoring in gltfio. I feel that
the high-level objects have become too tightly coupled to each other.
Fixes#3137.