gltfio: various cleanup in response to PR review

This commit is contained in:
Philip Rideout
2020-02-01 16:48:13 -08:00
parent d2c883877d
commit e8e847a662
7 changed files with 48 additions and 35 deletions

View File

@@ -64,8 +64,13 @@ public class FilamentAsset {
/**
* Pops a ready renderable off the queue, or returns 0 if no renderables have become ready.
*
* NOTE: To determine the progress percentage or completion status, please use
* ResourceLoader#asyncGetLoadProgress.
*
* This helper method allows clients to progressively add renderables to the scene as textures
* gradually become ready through asynchronous loading.
*
* See also ResourceLoader#asyncBeginLoad.
*/
public @Entity int popRenderable() {
return nPopRenderable(mNativeObject);

View File

@@ -75,9 +75,12 @@ public:
/**
* Pops a ready renderable off the queue, or returns 0 if no renderables have become ready.
*
* This helper method allows clients to progressively add renderables to the scene as textures
* gradually become ready through asynchronous loading. For example, on every frame progressive
* applications can do something like this:
* NOTE: To determine the progress percentage or completion status, please use
* ResourceLoader#asyncGetLoadProgress.
*
* This method allows clients to progressively add the asset's renderables to the scene as
* textures gradually become ready through asynchronous loading. For example, on every frame
* progressive applications can do something like this:
*
* while (utils::Entity e = popRenderable()) { scene.addEntity(e); }
*

View File

@@ -69,17 +69,16 @@ public:
~SimpleViewer();
/**
* Sets or changes the asset that is being viewed.
* Adds the asset's ready-to-render entities into the scene and optionally transforms the root
* node to make it fit into a unit cube at the origin.
*
* This adds all the asset's entities into the scene and optionally transforms the asset to make
* it fit into a unit cube at the origin. The viewer does not claim ownership over the asset or
* its entities. Clients should use AssetLoader and ResourceLoader to load an asset before
* passing it in.
* The viewer does not claim ownership over the asset or its entities. Clients should use
* AssetLoader and ResourceLoader to load an asset before passing it in.
*
* @param asset The asset to view.
* @param scale Adds a transform to the root to fit the asset into a unit cube at the origin.
*/
void setAsset(FilamentAsset* asset, bool scale);
void populateScene(FilamentAsset* asset, bool scale);
/**
* Removes the current asset from the viewer.
@@ -257,7 +256,7 @@ SimpleViewer::~SimpleViewer() {
mEngine->destroy(mSunlight);
}
void SimpleViewer::setAsset(FilamentAsset* asset, bool scale) {
void SimpleViewer::populateScene(FilamentAsset* asset, bool scale) {
if (mAsset == asset) {
while (utils::Entity e = mAsset->popRenderable()) {
mScene->addEntity(e);

View File

@@ -59,7 +59,7 @@ void DependencyGraph::addEdge(Texture* texture, MaterialInstance* material, cons
void DependencyGraph::markAsReady(Texture* texture) {
assert(texture && mFinalized);
mTextures.at(texture)->ready = true;
mTextureNodes.at(texture)->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.
@@ -94,10 +94,10 @@ void DependencyGraph::markAsReady(MaterialInstance* material) {
}
}
DependencyGraph::TextureStatus* DependencyGraph::getStatus(Texture* texture) {
auto iter = mTextures.find(texture);
if (iter == mTextures.end()) {
TextureStatus* status = (mTextures[texture] = std::make_unique<TextureStatus>()).get();
DependencyGraph::TextureNode* DependencyGraph::getStatus(Texture* texture) {
auto iter = mTextureNodes.find(texture);
if (iter == mTextureNodes.end()) {
TextureNode* status = (mTextureNodes[texture] = std::make_unique<TextureNode>()).get();
*status = {texture, false};
return status;
}

View File

@@ -43,16 +43,16 @@ namespace gltfio {
* One graph corresponds to a single glTF asset. The graph only contains weak references, it does
* not have ownership over any Filament objects. Here's an example:
*
* Entity Entity Entity Entity
* | / \ | /
* | / \ | /
* Material Material Material
* / | \ |
* / | \ |
* Param Param Param Param
* \ / \ /
* \ / \ /
* Texture Texture
* Entity Entity Entity Entity
* | / \ | /
* | / \ | /
* Material Material Material
* / | \ |
* / | \ |
* Param Param Param Param
* \ / | |
* \ / | |
* Texture Texture Texture
*
* Note that the left-most entity in the above graph has no textures, so it becomes ready as soon as
* finalize is called.
@@ -77,28 +77,34 @@ public:
void markAsReady(filament::Texture* texture);
private:
struct TextureStatus {
struct TextureNode {
filament::Texture* texture;
bool ready;
};
struct MaterialStatus {
tsl::robin_map<std::string, TextureStatus*> params;
struct MaterialNode {
tsl::robin_map<std::string, TextureNode*> params;
};
struct EntityStatus {
struct EntityNode {
tsl::robin_set<Material*> materials;
size_t numReadyMaterials = 0;
};
void markAsReady(Material* material);
TextureStatus* getStatus(filament::Texture* texture);
TextureNode* getStatus(filament::Texture* texture);
tsl::robin_map<Entity, EntityStatus> mEntityToMaterial;
// The following maps contain the directed edges in the graph.
tsl::robin_map<Entity, EntityNode> mEntityToMaterial;
tsl::robin_map<Material*, tsl::robin_set<Entity>> mMaterialToEntity;
tsl::robin_map<Material*, MaterialStatus> mMaterialToTexture;
tsl::robin_map<Material*, MaterialNode> mMaterialToTexture;
tsl::robin_map<filament::Texture*, tsl::robin_set<Material*>> mTextureToMaterial;
tsl::robin_map<filament::Texture*, std::unique_ptr<TextureStatus>> mTextures;
// Each texture (and its readiness flag) can be referenced from multiple nodes, so we own
// a collection of wrapper objects in the following map. This uses std::unique_ptr to allow
// nodes to refer to a texture wrapper using a stable weak pointer.
tsl::robin_map<filament::Texture*, std::unique_ptr<TextureNode>> mTextureNodes;
std::queue<Entity> mReadyRenderables;
bool mFinalized = false;
};

View File

@@ -332,7 +332,7 @@ static void updateViewerMesh(BakerApp& app) {
app.viewerAsset->getAnimator();
// Remove old renderables and add new renderables to the scene.
app.viewer->setAsset(app.viewerAsset, !app.viewerActualSize);
app.viewer->populateScene(app.viewerAsset, !app.viewerActualSize);
// Destory old Filament entities.
app.loader->destroyAsset(previousViewerAsset);

View File

@@ -261,7 +261,7 @@ int main(int argc, char** argv) {
app.resourceLoader->asyncUpdateLoad();
// Add renderables to the scene as they become ready.
app.viewer->setAsset(app.asset, !app.actualSize);
app.viewer->populateScene(app.asset, !app.actualSize);
app.viewer->applyAnimation(now);
};