Optimize mesh by merging similar primitive groups

pull/1356/head
Hleb Valoshka 2022-01-25 20:08:25 +02:00
parent dee6a216f7
commit ca80f4448a
2 changed files with 59 additions and 0 deletions

View File

@ -14,9 +14,11 @@
#include <iterator>
#include <tuple>
#include <utility>
#include <celutil/logger.h>
#include "mesh.h"
using celestia::util::GetLogger;
namespace cmod
{
@ -393,9 +395,65 @@ Mesh::aggregateByMaterial()
{
return g0.materialIndex < g1.materialIndex;
});
mergePrimitiveGroups();
}
void
Mesh::mergePrimitiveGroups()
{
if (groups.size() < 2)
return;
std::vector<PrimitiveGroup> newGroups;
for (size_t i = 0; i < groups.size(); i++)
{
auto &g = groups[i];
if (g.vertexCountOverride == 0 && g.prim == PrimitiveGroupType::TriStrip)
{
std::vector<Index32> newIndices;
newIndices.reserve(g.indices.size() * 2);
for (size_t j = 0, e = g.indices.size() - 2; j < e; j++)
{
auto x = g.indices[j + 0];
auto y = g.indices[j + 1];
auto z = g.indices[j + 2];
// skip degenerated triangles
if (x == y || y == z || z == x)
continue;
if ((j & 1) != 0) // FIXME: CCW hardcoded
std::swap(y, z);
newIndices.push_back(x);
newIndices.push_back(y);
newIndices.push_back(z);
}
g.indices = std::move(newIndices);
g.prim = PrimitiveGroupType::TriList;
}
if (i == 0 || g.vertexCountOverride != 0 || g.prim != PrimitiveGroupType::TriList)
{
newGroups.push_back(std::move(g));
}
else
{
auto &p = newGroups.back();
if (p.prim != g.prim || p.materialIndex != g.materialIndex)
{
newGroups.push_back(std::move(g));
}
else
{
p.indices.reserve(p.indices.size() + g.indices.size());
p.indices.insert(p.indices.end(), g.indices.begin(), g.indices.end());
}
}
}
GetLogger()->info("Optimized mesh groups: had {} groups, now: {} of them.\n", groups.size(), newGroups.size());
groups = std::move(newGroups);
}
bool
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
{

View File

@ -239,6 +239,7 @@ class Mesh
private:
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
void mergePrimitiveGroups();
VertexDescription vertexDesc{ };