mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-07 10:02:24 +02:00
Add extent calculation utilities, CalculateExtentsTask, make tangent
calculation more lenient
This commit is contained in:
parent
da4ffcd91b
commit
09f584818b
6 changed files with 181 additions and 4 deletions
66
libraries/hfm/src/hfm/HFMModelMath.cpp
Normal file
66
libraries/hfm/src/hfm/HFMModelMath.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// HFMModelMath.cpp
|
||||
// model-baker/src/model-baker
|
||||
//
|
||||
// Created by Sabrina Shanman on 2019/10/04.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "HFMModelMath.h"
|
||||
|
||||
namespace hfm {
|
||||
|
||||
void forEachIndex(const hfm::MeshPart& meshPart, std::function<void(uint32_t)> func) {
|
||||
for (int i = 0; i <= meshPart.quadIndices.size() - 4; i += 4) {
|
||||
func((uint32_t)meshPart.quadIndices[i]);
|
||||
func((uint32_t)meshPart.quadIndices[i+1]);
|
||||
func((uint32_t)meshPart.quadIndices[i+2]);
|
||||
func((uint32_t)meshPart.quadIndices[i+3]);
|
||||
}
|
||||
for (int i = 0; i <= meshPart.triangleIndices.size() - 3; i += 3) {
|
||||
func((uint32_t)meshPart.triangleIndices[i]);
|
||||
func((uint32_t)meshPart.triangleIndices[i+1]);
|
||||
func((uint32_t)meshPart.triangleIndices[i+2]);
|
||||
}
|
||||
}
|
||||
|
||||
void thickenFlatExtents(Extents& extents) {
|
||||
// Add epsilon to extents to compensate for flat plane
|
||||
extents.minimum -= glm::vec3(EPSILON, EPSILON, EPSILON);
|
||||
extents.maximum += glm::vec3(EPSILON, EPSILON, EPSILON);
|
||||
}
|
||||
|
||||
void calculateExtentsForShape(hfm::Shape& shape, const std::vector<hfm::Mesh>& meshes, const std::vector<hfm::Joint> joints) {
|
||||
auto& shapeExtents = shape.transformedExtents;
|
||||
shapeExtents.reset();
|
||||
|
||||
const auto& mesh = meshes[shape.mesh];
|
||||
const auto& meshPart = mesh.parts[shape.meshPart];
|
||||
|
||||
glm::mat4 globalTransform = joints[shape.transform].globalTransform;
|
||||
forEachIndex(meshPart, [&](int32_t idx){
|
||||
if (mesh.vertices.size() <= idx) {
|
||||
return;
|
||||
}
|
||||
const glm::vec3& vertex = mesh.vertices[idx];
|
||||
const glm::vec3 transformedVertex = glm::vec3(globalTransform * glm::vec4(vertex, 1.0f));
|
||||
shapeExtents.addPoint(vertex);
|
||||
});
|
||||
|
||||
thickenFlatExtents(shapeExtents);
|
||||
}
|
||||
|
||||
void calculateExtentsForModel(Extents& modelExtents, const std::vector<hfm::Shape>& shapes) {
|
||||
modelExtents.reset();
|
||||
|
||||
for (size_t i = 0; i < shapes.size(); ++i) {
|
||||
const auto& shape = shapes[i];
|
||||
const auto& shapeExtents = shape.transformedExtents;
|
||||
modelExtents.addExtents(shapeExtents);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
30
libraries/hfm/src/hfm/HFMModelMath.h
Normal file
30
libraries/hfm/src/hfm/HFMModelMath.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// HFMModelMath.h
|
||||
// model-baker/src/model-baker
|
||||
//
|
||||
// Created by Sabrina Shanman on 2019/10/04.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_hfm_ModelMath_h
|
||||
#define hifi_hfm_ModelMath_h
|
||||
|
||||
#include "HFM.h"
|
||||
|
||||
namespace hfm {
|
||||
|
||||
void forEachIndex(const hfm::MeshPart& meshPart, std::function<void(uint32_t)> func);
|
||||
|
||||
void initializeExtents(Extents& extents);
|
||||
|
||||
// This can't be moved to model-baker until
|
||||
void calculateExtentsForShape(hfm::Shape& shape, const std::vector<hfm::Mesh>& meshes, const std::vector<hfm::Joint> joints);
|
||||
|
||||
void calculateExtentsForModel(Extents& modelExtents, const std::vector<hfm::Shape>& shapes);
|
||||
|
||||
};
|
||||
|
||||
#endif // #define hifi_hfm_ModelMath_h
|
|
@ -21,6 +21,7 @@
|
|||
#include "CalculateBlendshapeNormalsTask.h"
|
||||
#include "CalculateBlendshapeTangentsTask.h"
|
||||
#include "PrepareJointsTask.h"
|
||||
#include "CalculateExtentsTask.h"
|
||||
#include "BuildDracoMeshTask.h"
|
||||
#include "ParseFlowDataTask.h"
|
||||
|
||||
|
@ -29,7 +30,7 @@ namespace baker {
|
|||
class GetModelPartsTask {
|
||||
public:
|
||||
using Input = hfm::Model::Pointer;
|
||||
using Output = VaryingSet8<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::BlendshapesPerMesh, std::vector<hfm::Joint>, std::vector<hfm::Shape>, std::vector<hfm::DynamicTransform>, std::vector<hfm::Deformer>>;
|
||||
using Output = VaryingSet9<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::BlendshapesPerMesh, std::vector<hfm::Joint>, std::vector<hfm::Shape>, std::vector<hfm::DynamicTransform>, std::vector<hfm::Deformer>, Extents>;
|
||||
using JobModel = Job::ModelIO<GetModelPartsTask, Input, Output>;
|
||||
|
||||
void run(const BakeContextPointer& context, const Input& input, Output& output) {
|
||||
|
@ -46,6 +47,7 @@ namespace baker {
|
|||
output.edit5() = hfmModelIn->shapes;
|
||||
output.edit6() = hfmModelIn->dynamicTransforms;
|
||||
output.edit7() = hfmModelIn->deformers;
|
||||
output.edit8() = hfmModelIn->meshExtents;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -106,7 +108,7 @@ namespace baker {
|
|||
|
||||
class BuildModelTask {
|
||||
public:
|
||||
using Input = VaryingSet7<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>, FlowData, std::vector<ShapeVertices>>;
|
||||
using Input = VaryingSet9<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>, FlowData, std::vector<ShapeVertices>, std::vector<hfm::Shape>, Extents>;
|
||||
using Output = hfm::Model::Pointer;
|
||||
using JobModel = Job::ModelIO<BuildModelTask, Input, Output>;
|
||||
|
||||
|
@ -118,6 +120,8 @@ namespace baker {
|
|||
hfmModelOut->jointIndices = input.get4();
|
||||
hfmModelOut->flowData = input.get5();
|
||||
hfmModelOut->shapeVertices = input.get6();
|
||||
hfmModelOut->shapes = input.get7();
|
||||
hfmModelOut->meshExtents = input.get8();
|
||||
// These depend on the ShapeVertices
|
||||
// TODO: Create a task for this rather than calculating it here
|
||||
hfmModelOut->computeKdops();
|
||||
|
@ -145,6 +149,7 @@ namespace baker {
|
|||
const auto shapesIn = modelPartsIn.getN<GetModelPartsTask::Output>(5);
|
||||
const auto dynamicTransformsIn = modelPartsIn.getN<GetModelPartsTask::Output>(6);
|
||||
const auto deformersIn = modelPartsIn.getN<GetModelPartsTask::Output>(7);
|
||||
const auto modelExtentsIn = modelPartsIn.getN<GetModelPartsTask::Output>(8);
|
||||
|
||||
// Calculate normals and tangents for meshes and blendshapes if they do not exist
|
||||
// Note: Normals are never calculated here for OBJ models. OBJ files optionally define normals on a per-face basis, so for consistency normals are calculated beforehand in OBJSerializer.
|
||||
|
@ -175,6 +180,12 @@ namespace baker {
|
|||
const auto jointRotationOffsets = jointInfoOut.getN<PrepareJointsTask::Output>(1);
|
||||
const auto jointIndices = jointInfoOut.getN<PrepareJointsTask::Output>(2);
|
||||
|
||||
// Use transform information to compute extents
|
||||
const auto calculateExtentsInputs = CalculateExtentsTask::Input(modelExtentsIn, meshesIn, shapesIn, jointsOut).asVarying();
|
||||
const auto calculateExtentsOutputs = model.addJob<CalculateExtentsTask>("CalculateExtents", calculateExtentsInputs);
|
||||
const auto modelExtentsOut = calculateExtentsOutputs.getN<CalculateExtentsTask::Output>(0);
|
||||
const auto shapesOut = calculateExtentsOutputs.getN<CalculateExtentsTask::Output>(1);
|
||||
|
||||
// Parse material mapping
|
||||
const auto parseMaterialMappingInputs = ParseMaterialMappingTask::Input(mapping, materialMappingBaseURL).asVarying();
|
||||
const auto materialMapping = model.addJob<ParseMaterialMappingTask>("ParseMaterialMapping", parseMaterialMappingInputs);
|
||||
|
@ -198,7 +209,7 @@ namespace baker {
|
|||
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
|
||||
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, 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).asVarying();
|
||||
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData, shapeVerticesPerJoint, shapesOut, modelExtentsOut).asVarying();
|
||||
const auto hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
|
||||
|
||||
output = Output(hfmModelOut, materialMapping, dracoMeshes, dracoErrors, materialList);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// CalculateExtentsTask.cpp
|
||||
// model-baker/src/model-baker
|
||||
//
|
||||
// Created by Sabrina Shanman on 2019/10/04.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "CalculateExtentsTask.h"
|
||||
|
||||
#include "hfm/HFMModelMath.h"
|
||||
|
||||
void CalculateExtentsTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
||||
const auto& modelExtentsIn = input.get0();
|
||||
const auto& meshes = input.get1();
|
||||
const auto& shapesIn = input.get2();
|
||||
const auto& joints = input.get3();
|
||||
auto& modelExtentsOut = output.edit0();
|
||||
auto& shapesOut = output.edit1();
|
||||
|
||||
shapesOut.reserve(shapesIn.size());
|
||||
for (size_t i = 0; i < shapesIn.size(); ++i) {
|
||||
shapesOut.push_back(shapesIn[i]);
|
||||
auto& shapeOut = shapesOut.back();
|
||||
|
||||
auto& shapeExtents = shapeOut.transformedExtents;
|
||||
if (shapeExtents.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hfm::calculateExtentsForShape(shapeOut, meshes, joints);
|
||||
}
|
||||
|
||||
modelExtentsOut = modelExtentsIn;
|
||||
if (!modelExtentsOut.isValid()) {
|
||||
hfm::calculateExtentsForModel(modelExtentsOut, shapesOut);
|
||||
}
|
||||
}
|
29
libraries/model-baker/src/model-baker/CalculateExtentsTask.h
Normal file
29
libraries/model-baker/src/model-baker/CalculateExtentsTask.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// CalculateExtentsTask.h
|
||||
// model-baker/src/model-baker
|
||||
//
|
||||
// Created by Sabrina Shanman on 2019/10/04.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_CalculateExtentsTask_h
|
||||
#define hifi_CalculateExtentsTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
#include "hfm/HFM.h"
|
||||
|
||||
// Calculates any undefined extents in the shapes and the model. Precalculated extents will be left alone.
|
||||
// Bind extents will currently not be calculated
|
||||
class CalculateExtentsTask {
|
||||
public:
|
||||
using Input = baker::VaryingSet4<Extents, std::vector<hfm::Mesh>, std::vector<hfm::Shape>, std::vector<hfm::Joint>>;
|
||||
using Output = baker::VaryingSet2<Extents, std::vector<hfm::Shape>>;
|
||||
using JobModel = baker::Job::ModelIO<CalculateExtentsTask, Input, Output>;
|
||||
|
||||
void run(const baker::BakeContextPointer& context, const Input& input, Output& output);
|
||||
};
|
||||
|
||||
#endif // hifi_CalculateExtentsTask_h
|
|
@ -30,7 +30,7 @@ void CalculateMeshTangentsTask::run(const baker::BakeContextPointer& context, co
|
|||
// Otherwise confirm if we have the normals and texcoords needed
|
||||
if (!tangentsIn.empty()) {
|
||||
tangentsOut = tangentsIn.toStdVector();
|
||||
} else if (!normals.empty() && mesh.vertices.size() == mesh.texCoords.size()) {
|
||||
} else if (!normals.empty() && mesh.vertices.size() <= mesh.texCoords.size()) {
|
||||
tangentsOut.resize(normals.size());
|
||||
baker::calculateTangents(mesh,
|
||||
[&mesh, &normals, &tangentsOut](int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec2* outTexCoords, glm::vec3& outNormal) {
|
||||
|
|
Loading…
Reference in a new issue