Apply kdop computation after reading the joint rotation offsets

This commit is contained in:
luiscuenca 2019-03-04 13:15:15 -07:00
parent 8785f733db
commit 79b7a3d28d
5 changed files with 61 additions and 55 deletions

View file

@ -301,8 +301,6 @@ QString getString(const QVariant& value) {
return list.isEmpty() ? value.toString() : list.at(0).toString();
}
typedef std::vector<glm::vec3> ShapeVertices;
class AnimationCurve {
public:
QVector<float> values;
@ -1319,8 +1317,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
}
// NOTE: shapeVertices are in joint-frame
std::vector<ShapeVertices> shapeVertices;
shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
hfmModel.shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
hfmModel.bindExtents.reset();
hfmModel.meshExtents.reset();
@ -1511,7 +1508,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
}
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
ShapeVertices& points = shapeVertices.at(jointIndex);
ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
for (int j = 0; j < cluster.indices.size(); j++) {
int oldIndex = cluster.indices.at(j);
@ -1580,7 +1577,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
// transform cluster vertices to joint-frame and save for later
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
ShapeVertices& points = shapeVertices.at(jointIndex);
ShapeVertices& points = hfmModel.shapeVertices.at(jointIndex);
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertex);
points.push_back(extractTranslation(vertexTransform));
@ -1600,54 +1597,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
meshIDsToMeshIndices.insert(it.key(), meshIndex);
}
const float INV_SQRT_3 = 0.57735026918f;
ShapeVertices cardinalDirections = {
Vectors::UNIT_X,
Vectors::UNIT_Y,
Vectors::UNIT_Z,
glm::vec3(INV_SQRT_3, INV_SQRT_3, INV_SQRT_3),
glm::vec3(INV_SQRT_3, -INV_SQRT_3, INV_SQRT_3),
glm::vec3(INV_SQRT_3, INV_SQRT_3, -INV_SQRT_3),
glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
};
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
for (int i = 0; i < hfmModel.joints.size(); ++i) {
HFMJoint& joint = hfmModel.joints[i];
// NOTE: points are in joint-frame
ShapeVertices& points = shapeVertices.at(i);
if (points.size() > 0) {
// compute average point
glm::vec3 avgPoint = glm::vec3(0.0f);
for (uint32_t j = 0; j < points.size(); ++j) {
avgPoint += points[j];
}
avgPoint /= (float)points.size();
joint.shapeInfo.avgPoint = avgPoint;
// compute a k-Dop bounding volume
for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
float maxDot = -FLT_MAX;
float minDot = FLT_MIN;
for (uint32_t k = 0; k < points.size(); ++k) {
float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
if (kDot > maxDot) {
maxDot = kDot;
}
if (kDot < minDot) {
minDot = kDot;
}
}
joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
joint.shapeInfo.dots.push_back(maxDot);
joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
joint.shapeInfo.dots.push_back(-minDot);
}
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
}
}
// attempt to map any meshes to a named model
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
m != meshIDsToMeshIndices.constEnd(); m++) {

View file

@ -154,3 +154,55 @@ QString HFMModel::getModelNameOfMesh(int meshIndex) const {
}
return QString();
}
void HFMModel::computeKdops() {
const float INV_SQRT_3 = 0.57735026918f;
ShapeVertices cardinalDirections = {
Vectors::UNIT_X,
Vectors::UNIT_Y,
Vectors::UNIT_Z,
glm::vec3(INV_SQRT_3, INV_SQRT_3, INV_SQRT_3),
glm::vec3(INV_SQRT_3, -INV_SQRT_3, INV_SQRT_3),
glm::vec3(INV_SQRT_3, INV_SQRT_3, -INV_SQRT_3),
glm::vec3(INV_SQRT_3, -INV_SQRT_3, -INV_SQRT_3)
};
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
for (int i = 0; i < joints.size(); ++i) {
HFMJoint& joint = joints[i];
// NOTE: points are in joint-frame
ShapeVertices& points = shapeVertices.at(i);
glm::quat rotOffset = jointRotationOffsets.contains(i) ? glm::inverse(jointRotationOffsets[i]) : quat();
if (points.size() > 0) {
// compute average point
glm::vec3 avgPoint = glm::vec3(0.0f);
for (uint32_t j = 0; j < points.size(); ++j) {
points[j] = rotOffset * points[j];
avgPoint += points[j];
}
avgPoint /= (float)points.size();
joint.shapeInfo.avgPoint = avgPoint;
// compute a k-Dop bounding volume
for (uint32_t j = 0; j < cardinalDirections.size(); ++j) {
float maxDot = -FLT_MAX;
float minDot = FLT_MIN;
for (uint32_t k = 0; k < points.size(); ++k) {
float kDot = glm::dot(cardinalDirections[j], points[k] - avgPoint);
if (kDot > maxDot) {
maxDot = kDot;
}
if (kDot < minDot) {
minDot = kDot;
}
}
joint.shapeInfo.points.push_back(avgPoint + maxDot * cardinalDirections[j]);
joint.shapeInfo.dots.push_back(maxDot);
joint.shapeInfo.points.push_back(avgPoint + minDot * cardinalDirections[j]);
joint.shapeInfo.dots.push_back(-minDot);
}
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
}
}
}

View file

@ -53,6 +53,8 @@ using ColorType = glm::vec3;
const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
using ShapeVertices = std::vector<glm::vec3>;
// High Fidelity Model namespace
namespace hfm {
@ -319,6 +321,8 @@ public:
QList<QString> blendshapeChannelNames;
QMap<int, glm::quat> jointRotationOffsets;
std::vector<ShapeVertices> shapeVertices;
void computeKdops();
};
};

View file

@ -111,6 +111,7 @@ namespace baker {
hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
hfmModelOut->jointRotationOffsets = input.get3();
hfmModelOut->jointIndices = input.get4();
hfmModelOut->computeKdops();
output = hfmModelOut;
}
};

View file

@ -436,7 +436,7 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& minCorner, const
float z = scale.z;
float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
float halfHeight = 0.5f * scale.y - radius;
float MIN_HALF_HEIGHT = 0.1f;
float MIN_HALF_HEIGHT = 0.0f;
if (halfHeight < MIN_HALF_HEIGHT) {
halfHeight = MIN_HALF_HEIGHT;
}