mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 14:39:45 +02:00
Compute the bone radii from the vertices. It's more error-prone than I
expected, but it more or less works.
This commit is contained in:
parent
44f92fb47c
commit
2633223f4e
4 changed files with 60 additions and 4 deletions
|
@ -224,6 +224,15 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) {
|
|||
0.5f * sqrtf(z2) * (upper[0][1] >= upper[1][0] ? 1.0f : -1.0f)));
|
||||
}
|
||||
|
||||
glm::vec3 extractScale(const glm::mat4& matrix) {
|
||||
return glm::vec3(glm::length(matrix[0]), glm::length(matrix[1]), glm::length(matrix[2]));
|
||||
}
|
||||
|
||||
float extractUniformScale(const glm::mat4& matrix) {
|
||||
glm::vec3 scale = extractScale(matrix);
|
||||
return (scale.x + scale.y + scale.z) / 3.0f;
|
||||
}
|
||||
|
||||
// Draw a 3D vector floating in space
|
||||
void drawVector(glm::vec3 * vector) {
|
||||
glDisable(GL_LIGHTING);
|
||||
|
|
|
@ -61,6 +61,10 @@ void setTranslation(glm::mat4& matrix, const glm::vec3& translation);
|
|||
|
||||
glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal = false);
|
||||
|
||||
glm::vec3 extractScale(const glm::mat4& matrix);
|
||||
|
||||
float extractUniformScale(const glm::mat4& matrix);
|
||||
|
||||
double diffclock(timeval *clock1,timeval *clock2);
|
||||
|
||||
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <OctalCode.h>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <VoxelTree.h>
|
||||
|
||||
#include "FBXReader.h"
|
||||
|
@ -1142,6 +1143,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
joint.distanceToParent = glm::distance(extractTranslation(parentJoint.transform),
|
||||
extractTranslation(joint.transform));
|
||||
}
|
||||
joint.boneRadius = 0.0f;
|
||||
joint.inverseBindRotation = joint.inverseDefaultRotation;
|
||||
geometry.joints.append(joint);
|
||||
geometry.jointIndices.insert(model.name, geometry.joints.size() - 1);
|
||||
|
@ -1274,7 +1276,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
}
|
||||
|
||||
// whether we're skinned depends on how many clusters are attached
|
||||
int maxJointIndex = extracted.mesh.clusters.at(0).jointIndex;
|
||||
const FBXCluster& firstFBXCluster = extracted.mesh.clusters.at(0);
|
||||
int maxJointIndex = firstFBXCluster.jointIndex;
|
||||
glm::mat4 inverseModelTransform = glm::inverse(modelTransform);
|
||||
if (clusterIDs.size() > 1) {
|
||||
extracted.mesh.clusterIndices.resize(extracted.mesh.vertices.size());
|
||||
extracted.mesh.clusterWeights.resize(extracted.mesh.vertices.size());
|
||||
|
@ -1282,6 +1286,21 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
for (int i = 0; i < clusterIDs.size(); i++) {
|
||||
QString clusterID = clusterIDs.at(i);
|
||||
const Cluster& cluster = clusters[clusterID];
|
||||
const FBXCluster& fbxCluster = extracted.mesh.clusters.at(i);
|
||||
int jointIndex = fbxCluster.jointIndex;
|
||||
FBXJoint& joint = geometry.joints[jointIndex];
|
||||
glm::vec3 boneEnd = extractTranslation(inverseModelTransform * joint.bindTransform);
|
||||
glm::vec3 boneDirection;
|
||||
float boneLength;
|
||||
if (joint.parentIndex != -1) {
|
||||
boneDirection = boneEnd - extractTranslation(inverseModelTransform *
|
||||
geometry.joints[joint.parentIndex].bindTransform);
|
||||
boneLength = glm::length(boneDirection);
|
||||
if (boneLength > EPSILON) {
|
||||
boneDirection /= boneLength;
|
||||
}
|
||||
}
|
||||
float radiusScale = extractUniformScale(joint.transform * fbxCluster.inverseBindMatrix);
|
||||
float totalWeight = 0.0f;
|
||||
for (int j = 0; j < cluster.indices.size(); j++) {
|
||||
int oldIndex = cluster.indices.at(j);
|
||||
|
@ -1289,9 +1308,18 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
totalWeight += weight;
|
||||
for (QMultiHash<int, int>::const_iterator it = extracted.newIndices.constFind(oldIndex);
|
||||
it != extracted.newIndices.end() && it.key() == oldIndex; it++) {
|
||||
glm::vec4& weights = extracted.mesh.clusterWeights[it.value()];
|
||||
|
||||
// expand the bone radius
|
||||
if (weight > 0.25f) {
|
||||
const glm::vec3& vertex = extracted.mesh.vertices.at(it.value());
|
||||
float proj = glm::dot(boneDirection, vertex - boneEnd);
|
||||
if (proj < 0.0f && proj > -boneLength) {
|
||||
joint.boneRadius = glm::max(joint.boneRadius, radiusScale * glm::distance(
|
||||
vertex, boneEnd + boneDirection * proj));
|
||||
} }
|
||||
|
||||
|
||||
// look for an unused slot in the weights vector
|
||||
glm::vec4& weights = extracted.mesh.clusterWeights[it.value()];
|
||||
for (int k = 0; k < 4; k++) {
|
||||
if (weights[k] == 0.0f) {
|
||||
extracted.mesh.clusterIndices[it.value()][k] = i;
|
||||
|
@ -1303,9 +1331,23 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
}
|
||||
if (totalWeight > maxWeight) {
|
||||
maxWeight = totalWeight;
|
||||
maxJointIndex = extracted.mesh.clusters.at(i).jointIndex;
|
||||
maxJointIndex = jointIndex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int jointIndex = maxJointIndex;
|
||||
FBXJoint& joint = geometry.joints[jointIndex];
|
||||
glm::vec3 boneEnd = extractTranslation(inverseModelTransform * joint.bindTransform);
|
||||
glm::vec3 boneStart = boneEnd;
|
||||
if (joint.parentIndex != -1) {
|
||||
boneStart = extractTranslation(inverseModelTransform * geometry.joints[joint.parentIndex].bindTransform);
|
||||
}
|
||||
float radiusScale = extractUniformScale(joint.transform * firstFBXCluster.inverseBindMatrix);
|
||||
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
||||
// expand the bone radius
|
||||
joint.boneRadius = glm::max(joint.boneRadius, radiusScale * glm::length(
|
||||
computeVectorFromPointToSegment(vertex, boneStart, boneEnd)));
|
||||
}
|
||||
}
|
||||
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
QVector<int> freeLineage;
|
||||
int parentIndex;
|
||||
float distanceToParent;
|
||||
float boneRadius;
|
||||
glm::mat4 preTransform;
|
||||
glm::quat preRotation;
|
||||
glm::quat rotation;
|
||||
|
|
Loading…
Reference in a new issue