From 8f1d4ffa4d36d4ae97a1b97607cd53d557e45a02 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Wed, 22 May 2019 11:47:12 -0700 Subject: [PATCH] gltf_baker now parameterizes in a background thread. --- libs/rays/src/PathTracer.cpp | 1 - samples/gltf_baker.cpp | 105 +++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/libs/rays/src/PathTracer.cpp b/libs/rays/src/PathTracer.cpp index e907fe7441..4a04b070a3 100644 --- a/libs/rays/src/PathTracer.cpp +++ b/libs/rays/src/PathTracer.cpp @@ -385,7 +385,6 @@ void spawnTileJobs(EmbreeContext* context, RenderFn render, CompletionFn done) { if (--context->numRemainingTiles == 0) { done(context); } - }); js->run(tile); } diff --git a/samples/gltf_baker.cpp b/samples/gltf_baker.cpp index 269b9840be..06b1cdf899 100644 --- a/samples/gltf_baker.cpp +++ b/samples/gltf_baker.cpp @@ -36,12 +36,13 @@ #include +#include +#include + #include #include -#include - #include #include #include @@ -90,11 +91,14 @@ struct App { MaterialInstance* overlayMaterial = nullptr; utils::Entity overlayEntity; AppState pushedState; + gltfio::AssetPipeline* pipeline; + uint32_t bakeResolution = 1024; + + // Secondary threads might write to the following fields. + std::shared_ptr statusText; + std::shared_ptr messageBoxText; std::atomic requestOverlayUpdate; std::atomic requestStatePop; - gltfio::AssetPipeline* pipeline; - std::string messageBoxText; - uint32_t bakeResolution = 1024; }; struct OverlayVertex { @@ -336,39 +340,58 @@ static void loadAsset(App& app) { static void prepAsset(App& app) { app.state = PREPPING; - gltfio::AssetPipeline::AssetHandle asset = app.asset->getSourceAsset(); - uint32_t flags = gltfio::AssetPipeline::FILTER_TRIANGLES; - if (app.enablePrepScale) { - flags |= gltfio::AssetPipeline::SCALE_TO_UNIT; - } - gltfio::AssetPipeline pipeline; - asset = pipeline.flatten(asset, flags); - if (!asset) { - std::cerr << "Unable to flatten " << app.filename << std::endl; - app.state = LOADED; - return; - } + utils::JobSystem* js = utils::JobSystem::getJobSystem(); + utils::JobSystem::Job* parent = js->createJob(); + utils::JobSystem::Job* prep = utils::jobs::createJob(*js, parent, [&app] { + gltfio::AssetPipeline::AssetHandle asset = app.asset->getSourceAsset(); + uint32_t flags = gltfio::AssetPipeline::FILTER_TRIANGLES; + if (app.enablePrepScale) { + flags |= gltfio::AssetPipeline::SCALE_TO_UNIT; + } + gltfio::AssetPipeline pipeline; - asset = pipeline.parameterize(asset); - if (!asset) { - std::cerr << "Unable to parameterize " << app.filename << std::endl; - app.state = LOADED; - app.messageBoxText = "Unable to parameterize mesh, check terminal output for details."; - return; - } + { + app.statusText = std::make_shared("Flattening"); + asset = pipeline.flatten(asset, flags); + app.statusText.reset(); + } - const utils::Path folder = app.filename.getAbsolutePath().getParent(); - const utils::Path binPath = folder + "prepped.bin"; - const utils::Path outPath = folder + "prepped.gltf"; + if (!asset) { + app.messageBoxText = std::make_shared("Unable to flatten model"); + app.pushedState = LOADED; + app.requestStatePop = true; + return; + } - pipeline.save(asset, outPath, binPath); - std::cout << "Generated " << outPath << " and " << binPath << std::endl; + { + app.statusText = std::make_shared("Parameterizing"); + asset = pipeline.parameterize(asset); + app.statusText.reset(); + } - app.filename = outPath; - loadAsset(app); + if (!asset) { + app.messageBoxText = std::make_shared( + "Unable to parameterize mesh, check terminal output for details."); + app.pushedState = LOADED; + app.requestStatePop = true; + return; + } - app.state = PREPPED; + const utils::Path folder = app.filename.getAbsolutePath().getParent(); + const utils::Path binPath = folder + "prepped.bin"; + const utils::Path outPath = folder + "prepped.gltf"; + + pipeline.save(asset, outPath, binPath); + std::cout << "Generated " << outPath << " and " << binPath << std::endl; + + app.filename = outPath; + loadAsset(app); + + app.pushedState = PREPPED; + app.requestStatePop = true; + }); + js->run(prep); } static void renderAsset(App& app) { @@ -629,14 +652,26 @@ int main(int argc, char** argv) { app.bakeResolution = 1 << (bakeOption + kFirstOption); } - if (!app.messageBoxText.empty()) { + if (app.statusText) { + // Apply a poor man's animation to the ellipsis to indicate that work is being done. + static const char* suffixes[] = { "...", "......", "........." }; + static float suffixAnim = 0; + suffixAnim += 0.05f; + const char* suffix = suffixes[int(suffixAnim) % 3]; + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10, 10} ); + ImGui::Text("%s%s", app.statusText->c_str(), suffix); + ImGui::PopStyleVar(); + } + + if (app.messageBoxText) { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10, 10} ); ImGui::OpenPopup("MessageBox"); if (ImGui::BeginPopupModal("MessageBox", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar)) { - ImGui::TextUnformatted(app.messageBoxText.c_str()); + ImGui::TextUnformatted(app.messageBoxText->c_str()); if (ImGui::Button("OK", ImVec2(120,0))) { - app.messageBoxText.clear(); + app.messageBoxText.reset(); ImGui::CloseCurrentPopup(); } ImGui::EndPopup();