Optimize mesh by merging similar primitive groups
parent
dee6a216f7
commit
ca80f4448a
|
@ -14,9 +14,11 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <celutil/logger.h>
|
||||||
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
|
||||||
|
using celestia::util::GetLogger;
|
||||||
|
|
||||||
namespace cmod
|
namespace cmod
|
||||||
{
|
{
|
||||||
|
@ -393,9 +395,65 @@ Mesh::aggregateByMaterial()
|
||||||
{
|
{
|
||||||
return g0.materialIndex < g1.materialIndex;
|
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
|
bool
|
||||||
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
|
Mesh::pick(const Eigen::Vector3d& rayOrigin, const Eigen::Vector3d& rayDirection, PickResult* result) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -239,6 +239,7 @@ class Mesh
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
|
PrimitiveGroup createLinePrimitiveGroup(bool lineStrip, const std::vector<Index32>& indices);
|
||||||
|
void mergePrimitiveGroups();
|
||||||
|
|
||||||
VertexDescription vertexDesc{ };
|
VertexDescription vertexDesc{ };
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue