From fbc8e584d806b1913d77467996758e74cdcd2bd0 Mon Sep 17 00:00:00 2001 From: Malin Ejdbo Date: Thu, 5 Nov 2020 15:52:07 +0100 Subject: [PATCH] Add support for list of model files in asset files * Load either one or several model files in asset files * In the case of several model files, combine all models into one single ModelGeometry --- ext/ghoul | 2 +- modules/base/rendering/renderablemodel.cpp | 55 ++++++++++++++++++---- modules/base/rendering/renderablemodel.h | 1 - 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index a171ea9e94..ab82304571 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit a171ea9e9432ce1f87546f9742d9082a5aa4affb +Subproject commit ab82304571e5d4f5c4d518385fc523da2b0b805b diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 03ea03770f..f4997a1462 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -115,9 +115,9 @@ documentation::Documentation RenderableModel::Documentation() { { { KeyGeomModelFile, - new StringVerifier, + new OrVerifier({ new StringVerifier, new StringListVerifier }), Optional::No, - "The file that should be loaded in this RenderableModel. The file can " + "The file or files that should be loaded in this RenderableModel. The file can " "contain filesystem tokens or can be specified relatively to the " "location of the .mod file. " "This specifies the model that is rendered by the Renderable." @@ -223,13 +223,52 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) } if (dictionary.hasKey(KeyGeomModelFile)) { - _file = absPath(dictionary.value(KeyGeomModelFile)); + std::string file; - // Read the file and save the resulting ModelGeometry - _geometry = ghoul::io::ModelReader::ref().loadModel(_file, - _forceRenderInvisible, - _notifyInvisibleDropped - ); + if (dictionary.hasKeyAndValue(KeyGeomModelFile)) { + // Handle single file + file = absPath(dictionary.value(KeyGeomModelFile)); + _geometry = ghoul::io::ModelReader::ref().loadModel( + file, + _forceRenderInvisible, + _notifyInvisibleDropped + ); + } + else if (dictionary.hasKeyAndValue(KeyGeomModelFile)) { + ghoul::Dictionary fileDictionary = dictionary.value( + KeyGeomModelFile + ); + std::vector> geometries; + + for (std::string k : fileDictionary.keys()) { + // Handle each file + file = absPath(fileDictionary.value(k)); + geometries.push_back(ghoul::io::ModelReader::ref().loadModel( + file, + _forceRenderInvisible, + _notifyInvisibleDropped + )); + } + + if (geometries.size() > 0) { + ghoul::modelgeometry::ModelGeometry combinedGeometry = + std::move(*geometries[0].release()); + + // Combine all models into one ModelGeometry + for (unsigned int i = 1; i < geometries.size(); ++i) { + for (unsigned int m = 0; m < geometries[i]->meshes().size(); ++m) { + combinedGeometry.meshes().push_back( + std::move(geometries[i]->meshes()[m]) + ); + + } + } + _geometry = std::make_unique( + std::move(combinedGeometry) + ); + _geometry->calculateBoundingRadius(); + } + } } if (dictionary.hasKey(ModelTransformInfo.identifier)) { diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index e2207fbe9d..ec4a585d7e 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -69,7 +69,6 @@ public: static documentation::Documentation Documentation(); private: - std::string _file; std::unique_ptr _geometry; bool _forceRenderInvisible = false; bool _notifyInvisibleDropped = true;