From f4bd55991f68bed06e88f1daee21917aae9cc395 Mon Sep 17 00:00:00 2001 From: Hleb Valoshka <375gnu@gmail.com> Date: Thu, 17 Feb 2022 23:01:11 +0200 Subject: [PATCH] Optimize meshes with meshoptimizer library if available --- CMakeLists.txt | 8 ++++++++ config.h.in | 1 + src/celestia/CMakeLists.txt | 4 ++++ src/celmodel/mesh.cpp | 20 ++++++++++++++++++++ src/celmodel/mesh.h | 1 + src/celmodel/model.cpp | 4 +++- 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcbbfaddd..12d5feb08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,6 +245,14 @@ endif() find_package(Freetype REQUIRED) link_libraries(Freetype::Freetype) +find_package(meshoptimizer CONFIG QUIET) +if(meshoptimizer_FOUND) + message(STATUS "Found meshoptimizer library") + set(HAVE_MESHOPTIMIZER 1) +else() + message(STATUS "meshoptimizer library is missing") +endif() + #[[ get_cmake_property(_variableNames VARIABLES) list (SORT _variableNames) diff --git a/config.h.in b/config.h.in index ddc068989..6675c4a0d 100644 --- a/config.h.in +++ b/config.h.in @@ -3,4 +3,5 @@ #cmakedefine HAVE_FLOAT_CHARCONV #cmakedefine HAVE_STD_FILESYSTEM #cmakedefine HAVE_WORDEXP +#cmakedefine HAVE_MESHOPTIMIZER #cmakedefine WORDS_BIGENDIAN diff --git a/src/celestia/CMakeLists.txt b/src/celestia/CMakeLists.txt index 405ece35a..ddf9884d0 100644 --- a/src/celestia/CMakeLists.txt +++ b/src/celestia/CMakeLists.txt @@ -80,6 +80,10 @@ if(ENABLE_FFMPEG) target_link_libraries(celestia ${FFMPEG_LIBRARIES}) endif() +if (HAVE_MESHOPTIMIZER) + target_link_libraries(celestia PRIVATE meshoptimizer::meshoptimizer) +endif() + install(TARGETS celestia LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_SKIP) add_subdirectory(glut) diff --git a/src/celmodel/mesh.cpp b/src/celmodel/mesh.cpp index 579f7cc00..809ebabc6 100644 --- a/src/celmodel/mesh.cpp +++ b/src/celmodel/mesh.cpp @@ -16,6 +16,10 @@ #include #include +#ifdef HAVE_MESHOPTIMIZER +#include +#endif + #include "mesh.h" using celestia::util::GetLogger; @@ -455,6 +459,21 @@ Mesh::mergePrimitiveGroups() groups = std::move(newGroups); } +void +Mesh::optimize() +{ +#ifdef HAVE_MESHOPTIMIZER + if (groups.size() > 1) + return; + + auto &g = groups.front(); + + meshopt_optimizeVertexCache(g.indices.data(), g.indices.data(), g.indices.size(), nVertices); + meshopt_optimizeOverdraw(g.indices.data(), g.indices.data(), g.indices.size(), reinterpret_cast(vertices.data()), nVertices, vertexDesc.strideBytes, 1.05f); + meshopt_optimizeVertexFetch(vertices.data(), g.indices.data(), g.indices.size(), vertices.data(), nVertices, vertexDesc.strideBytes); +#endif +} + bool Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const { @@ -769,4 +788,5 @@ Mesh::canMerge(const Mesh &other, const std::vector &materials) const return true; } + } // end namespace cmod diff --git a/src/celmodel/mesh.h b/src/celmodel/mesh.h index 68dbb2945..be3cd2bfa 100644 --- a/src/celmodel/mesh.h +++ b/src/celmodel/mesh.h @@ -239,6 +239,7 @@ class Mesh void merge(const Mesh&); bool canMerge(const Mesh&, const std::vector &materials) const; + void optimize(); private: PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector& indices); diff --git a/src/celmodel/model.cpp b/src/celmodel/model.cpp index def26e852..81ca1c23c 100644 --- a/src/celmodel/model.cpp +++ b/src/celmodel/model.cpp @@ -318,7 +318,6 @@ Model::usesTextureType(TextureSemantic t) const } - bool Model::OpacityComparator::operator()(const Mesh& a, const Mesh& b) const { @@ -353,6 +352,9 @@ Model::sortMeshes(const MeshComparator& comparator) p.merge(meshes[i]); } GetLogger()->info("Merged similar meshes: {} -> {}.\n", meshes.size(), newMeshes.size()); + + for (auto &mesh : newMeshes) + mesh.optimize(); meshes = std::move(newMeshes); }