mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 17:03:43 +02:00
Merge pull request #16431 from sabrina-shanman/instancing_slimmesh
(DEV-564) Introduce and populate geometry-only mesh representation from hfm::Mesh
This commit is contained in:
commit
ad0fce9c3b
5 changed files with 118 additions and 9 deletions
|
@ -229,6 +229,14 @@ public:
|
|||
bool needTangentSpace() const;
|
||||
};
|
||||
|
||||
|
||||
/// Simple Triangle List Mesh
|
||||
struct TriangleListMesh {
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
std::vector<glm::ivec2> parts; // Offset in the indices, Number of indices
|
||||
};
|
||||
|
||||
/// A single mesh (with optional blendshapes).
|
||||
class Mesh {
|
||||
public:
|
||||
|
@ -254,12 +262,15 @@ public:
|
|||
// Blendshape attributes
|
||||
QVector<Blendshape> blendshapes;
|
||||
|
||||
// Simple Triangle List Mesh generated during baking
|
||||
hfm::TriangleListMesh triangleListMesh;
|
||||
|
||||
QVector<int32_t> originalIndices; // Original indices of the vertices
|
||||
unsigned int meshIndex; // the order the meshes appeared in the object file
|
||||
|
||||
graphics::MeshPointer _mesh;
|
||||
bool wasCompressed { false };
|
||||
|
||||
};
|
||||
|
||||
/// A single animation frame.
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
#include "HFMModelMath.h"
|
||||
|
||||
#include <LogHandler.h>
|
||||
#include "ModelFormatLogging.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <glm/gtx/hash.hpp>
|
||||
|
||||
namespace hfm {
|
||||
|
||||
|
@ -139,4 +143,60 @@ ReweightedDeformers getReweightedDeformers(const size_t numMeshVertices, const s
|
|||
return reweightedDeformers;
|
||||
}
|
||||
|
||||
const TriangleListMesh generateTriangleListMesh(const std::vector<glm::vec3>& srcVertices, const std::vector<HFMMeshPart>& srcParts) {
|
||||
|
||||
TriangleListMesh dest;
|
||||
|
||||
// copy vertices for now
|
||||
dest.vertices = srcVertices;
|
||||
|
||||
std::vector<uint32_t> oldToNewIndex(srcVertices.size());
|
||||
{
|
||||
std::unordered_map<glm::vec3, uint32_t> uniqueVertexToNewIndex;
|
||||
int oldIndex = 0;
|
||||
int newIndex = 0;
|
||||
for (const auto& srcVertex : srcVertices) {
|
||||
auto foundIndex = uniqueVertexToNewIndex.find(srcVertex);
|
||||
if (foundIndex != uniqueVertexToNewIndex.end()) {
|
||||
oldToNewIndex[oldIndex] = foundIndex->second;
|
||||
} else {
|
||||
uniqueVertexToNewIndex[srcVertex] = newIndex;
|
||||
oldToNewIndex[oldIndex] = newIndex;
|
||||
dest.vertices[newIndex] = srcVertex;
|
||||
++newIndex;
|
||||
}
|
||||
++oldIndex;
|
||||
}
|
||||
if (uniqueVertexToNewIndex.size() < srcVertices.size()) {
|
||||
dest.vertices.resize(uniqueVertexToNewIndex.size());
|
||||
dest.vertices.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
auto newIndicesCount = 0;
|
||||
for (const auto& part : srcParts) {
|
||||
newIndicesCount += part.triangleIndices.size() + part.quadTrianglesIndices.size();
|
||||
}
|
||||
|
||||
{
|
||||
dest.indices.resize(newIndicesCount);
|
||||
int i = 0;
|
||||
for (const auto& part : srcParts) {
|
||||
glm::ivec2 spart(i, 0);
|
||||
for (const auto& qti : part.quadTrianglesIndices) {
|
||||
dest.indices[i] = oldToNewIndex[qti];
|
||||
++i;
|
||||
}
|
||||
for (const auto& ti : part.triangleIndices) {
|
||||
dest.indices[i] = oldToNewIndex[ti];
|
||||
++i;
|
||||
}
|
||||
spart.y = i - spart.x;
|
||||
dest.parts.push_back(spart);
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -25,8 +25,7 @@ void calculateExtentsForShape(hfm::Shape& shape, const std::vector<hfm::Mesh>& m
|
|||
|
||||
void calculateExtentsForModel(Extents& modelExtents, const std::vector<hfm::Shape>& shapes);
|
||||
|
||||
class ReweightedDeformers {
|
||||
public:
|
||||
struct ReweightedDeformers {
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<uint16_t> weights;
|
||||
uint16_t weightsPerVertex { 0 };
|
||||
|
@ -36,6 +35,9 @@ public:
|
|||
const uint16_t DEFAULT_SKINNING_WEIGHTS_PER_VERTEX = 4;
|
||||
|
||||
ReweightedDeformers getReweightedDeformers(const size_t numMeshVertices, const std::vector<hfm::SkinCluster> skinClusters, const uint16_t weightsPerVertex = DEFAULT_SKINNING_WEIGHTS_PER_VERTEX);
|
||||
|
||||
const TriangleListMesh generateTriangleListMesh(const std::vector<glm::vec3>& srcVertices, const std::vector<HFMMeshPart>& srcParts);
|
||||
|
||||
};
|
||||
|
||||
#endif // #define hifi_hfm_ModelMath_h
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "CalculateExtentsTask.h"
|
||||
#include "BuildDracoMeshTask.h"
|
||||
#include "ParseFlowDataTask.h"
|
||||
#include <hfm/HFMModelMath.h>
|
||||
|
||||
namespace baker {
|
||||
|
||||
|
@ -49,6 +50,26 @@ namespace baker {
|
|||
}
|
||||
};
|
||||
|
||||
class BuildMeshTriangleListTask {
|
||||
public:
|
||||
using Input = std::vector<hfm::Mesh>;
|
||||
using Output = std::vector<hfm::TriangleListMesh>;
|
||||
using JobModel = Job::ModelIO<BuildMeshTriangleListTask, Input, Output>;
|
||||
|
||||
void run(const BakeContextPointer& context, const Input& input, Output& output) {
|
||||
const auto& meshesIn = input;
|
||||
auto& indexedTrianglesMeshOut = output;
|
||||
indexedTrianglesMeshOut.clear();
|
||||
indexedTrianglesMeshOut.resize(meshesIn.size());
|
||||
|
||||
for (size_t i = 0; i < meshesIn.size(); i++) {
|
||||
auto& mesh = meshesIn[i];
|
||||
const auto verticesStd = mesh.vertices.toStdVector();
|
||||
indexedTrianglesMeshOut[i] = hfm::generateTriangleListMesh(verticesStd, mesh.parts);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BuildBlendshapesTask {
|
||||
public:
|
||||
using Input = VaryingSet3<BlendshapesPerMesh, std::vector<NormalsPerBlendshape>, std::vector<TangentsPerBlendshape>>;
|
||||
|
@ -80,21 +101,23 @@ namespace baker {
|
|||
|
||||
class BuildMeshesTask {
|
||||
public:
|
||||
using Input = VaryingSet5<std::vector<hfm::Mesh>, std::vector<graphics::MeshPointer>, NormalsPerMesh, TangentsPerMesh, BlendshapesPerMesh>;
|
||||
using Input = VaryingSet6<std::vector<hfm::Mesh>, std::vector<hfm::TriangleListMesh>, std::vector<graphics::MeshPointer>, NormalsPerMesh, TangentsPerMesh, BlendshapesPerMesh>;
|
||||
using Output = std::vector<hfm::Mesh>;
|
||||
using JobModel = Job::ModelIO<BuildMeshesTask, Input, Output>;
|
||||
|
||||
void run(const BakeContextPointer& context, const Input& input, Output& output) {
|
||||
auto& meshesIn = input.get0();
|
||||
int numMeshes = (int)meshesIn.size();
|
||||
auto& graphicsMeshesIn = input.get1();
|
||||
auto& normalsPerMeshIn = input.get2();
|
||||
auto& tangentsPerMeshIn = input.get3();
|
||||
auto& blendshapesPerMeshIn = input.get4();
|
||||
auto& triangleListMeshesIn = input.get1();
|
||||
auto& graphicsMeshesIn = input.get2();
|
||||
auto& normalsPerMeshIn = input.get3();
|
||||
auto& tangentsPerMeshIn = input.get4();
|
||||
auto& blendshapesPerMeshIn = input.get5();
|
||||
|
||||
auto meshesOut = meshesIn;
|
||||
for (int i = 0; i < numMeshes; i++) {
|
||||
auto& meshOut = meshesOut[i];
|
||||
meshOut.triangleListMesh = triangleListMeshesIn[i];
|
||||
meshOut._mesh = safeGet(graphicsMeshesIn, i);
|
||||
meshOut.normals = QVector<glm::vec3>::fromStdVector(safeGet(normalsPerMeshIn, i));
|
||||
meshOut.tangents = QVector<glm::vec3>::fromStdVector(safeGet(tangentsPerMeshIn, i));
|
||||
|
@ -162,6 +185,9 @@ namespace baker {
|
|||
const auto collectShapeVerticesInputs = CollectShapeVerticesTask::Input(meshesIn, shapesIn, jointsIn, skinDeformersIn).asVarying();
|
||||
const auto shapeVerticesPerJoint = model.addJob<CollectShapeVerticesTask>("CollectShapeVertices", collectShapeVerticesInputs);
|
||||
|
||||
// Build the slim triangle list mesh for each hfm::mesh
|
||||
const auto triangleListMeshes = model.addJob<BuildMeshTriangleListTask>("BuildMeshTriangleListTask", meshesIn);
|
||||
|
||||
// Build the graphics::MeshPointer for each hfm::Mesh
|
||||
const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, skinDeformersIn).asVarying();
|
||||
const auto graphicsMeshes = model.addJob<BuildGraphicsMeshTask>("BuildGraphicsMesh", buildGraphicsMeshInputs);
|
||||
|
@ -200,7 +226,7 @@ namespace baker {
|
|||
// Combine the outputs into a new hfm::Model
|
||||
const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying();
|
||||
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
|
||||
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
|
||||
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, triangleListMeshes, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
|
||||
const auto meshesOut = model.addJob<BuildMeshesTask>("BuildMeshes", buildMeshesInputs);
|
||||
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData, shapeVerticesPerJoint, shapesOut, modelExtentsOut).asVarying();
|
||||
const auto hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
|
||||
|
|
|
@ -392,4 +392,14 @@ inline glm::vec4 extractFov( const glm::mat4& m) {
|
|||
return result;
|
||||
}
|
||||
|
||||
inline bool operator<(const glm::vec3& lhs, const glm::vec3& rhs) {
|
||||
return (lhs.x < rhs.x) || (
|
||||
(lhs.x == rhs.x) && (
|
||||
(lhs.y < rhs.y) || (
|
||||
(lhs.y == rhs.y) && (lhs.z < rhs.z)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#endif // hifi_GLMHelpers_h
|
||||
|
|
Loading…
Reference in a new issue