gltfio: allow zero-instance assets.

This is a feature request from Google. It allows users to "preload" an
asset, ie you can now create all VertexBuffer objects, Texture objects,
etc, without actually creating any entities or renderable components.

In the past we used TransformManager to help out with computing the big
asset-level bounding box, but now we use `gltf_node_transform_world()`
because entities might not yet exist.

One minor side effect is that `FilamentAsset::getBoundingBox()` now
returns the AABB that was determined at load time, and does not account
for instances. As a result, our `gltf_instances` sample app looks
slightly different but this is expected.
This commit is contained in:
Philip Rideout
2022-09-14 16:40:47 -07:00
parent ad6a5eb4e1
commit c4abe4f46a
9 changed files with 88 additions and 32 deletions
+33 -7
View File
@@ -36,8 +36,15 @@ size_t DependencyGraph::popRenderables(Entity* result, size_t count) noexcept {
}
void DependencyGraph::addEdge(Entity entity, MaterialInstance* mi) {
mMaterialToEntity[mi].insert(entity);
mEntityToMaterial[entity].materials.insert(mi);
if (mDisabled) {
if (mEntityToMaterial.count(entity) == 0) {
mEntityToMaterial[entity] = {};
mReadyRenderables.push(entity);
}
} else {
mMaterialToEntity[mi].insert(entity);
mEntityToMaterial[entity].materials.insert(mi);
}
}
void DependencyGraph::addEdge(MaterialInstance* mi, const char* parameter) {
@@ -62,8 +69,10 @@ void DependencyGraph::commitEdges() {
void DependencyGraph::addEdge(Texture* texture, MaterialInstance* material, const char* parameter) {
assert_invariant(texture);
mTextureToMaterial[texture].insert(material);
mMaterialToTexture.at(material).params.at(parameter) = getStatus(texture);
if (!mDisabled) {
mTextureToMaterial[texture].insert(material);
mMaterialToTexture.at(material).params.at(parameter) = getStatus(texture);
}
}
void DependencyGraph::checkReadiness(Material* material) {
@@ -86,7 +95,11 @@ void DependencyGraph::checkReadiness(Material* material) {
void DependencyGraph::markAsReady(Texture* texture) {
assert_invariant(texture);
mTextureNodes.at(texture)->ready = true;
auto iter = mTextureNodes.find(texture);
if (iter == mTextureNodes.end()) {
return;
}
iter.value()->ready = true;
// Iterate over the materials associated with this texture to check if any have become ready.
// This is O(n2) but the inner loop is always small.
@@ -97,8 +110,12 @@ void DependencyGraph::markAsReady(Texture* texture) {
}
void DependencyGraph::markAsReady(MaterialInstance* material) {
auto& entities = mMaterialToEntity.at(material);
for (auto entity : entities) {
auto iter = mMaterialToEntity.find(material);
if (iter == mMaterialToEntity.end()) {
// It's fine if no entities exist yet.
return;
}
for (auto entity : iter->second) {
auto& status = mEntityToMaterial.at(entity);
assert_invariant(status.numReadyMaterials <= status.materials.size());
if (status.numReadyMaterials == status.materials.size()) {
@@ -121,4 +138,13 @@ DependencyGraph::TextureNode* DependencyGraph::getStatus(Texture* texture) {
return iter->second.get();
}
void DependencyGraph::disableProgressiveReveal() {
mDisabled = true;
for (auto& [entity, status] : mEntityToMaterial) {
if (status.numReadyMaterials < status.materials.size()) {
mReadyRenderables.push(entity);
}
}
}
} // namespace filament::gltfio