mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 12:28:02 +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)));
|
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
|
// Draw a 3D vector floating in space
|
||||||
void drawVector(glm::vec3 * vector) {
|
void drawVector(glm::vec3 * vector) {
|
||||||
glDisable(GL_LIGHTING);
|
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::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);
|
double diffclock(timeval *clock1,timeval *clock2);
|
||||||
|
|
||||||
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS);
|
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
|
|
||||||
|
#include <GeometryUtil.h>
|
||||||
#include <VoxelTree.h>
|
#include <VoxelTree.h>
|
||||||
|
|
||||||
#include "FBXReader.h"
|
#include "FBXReader.h"
|
||||||
|
@ -1142,6 +1143,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
joint.distanceToParent = glm::distance(extractTranslation(parentJoint.transform),
|
joint.distanceToParent = glm::distance(extractTranslation(parentJoint.transform),
|
||||||
extractTranslation(joint.transform));
|
extractTranslation(joint.transform));
|
||||||
}
|
}
|
||||||
|
joint.boneRadius = 0.0f;
|
||||||
joint.inverseBindRotation = joint.inverseDefaultRotation;
|
joint.inverseBindRotation = joint.inverseDefaultRotation;
|
||||||
geometry.joints.append(joint);
|
geometry.joints.append(joint);
|
||||||
geometry.jointIndices.insert(model.name, geometry.joints.size() - 1);
|
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
|
// 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) {
|
if (clusterIDs.size() > 1) {
|
||||||
extracted.mesh.clusterIndices.resize(extracted.mesh.vertices.size());
|
extracted.mesh.clusterIndices.resize(extracted.mesh.vertices.size());
|
||||||
extracted.mesh.clusterWeights.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++) {
|
for (int i = 0; i < clusterIDs.size(); i++) {
|
||||||
QString clusterID = clusterIDs.at(i);
|
QString clusterID = clusterIDs.at(i);
|
||||||
const Cluster& cluster = clusters[clusterID];
|
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;
|
float totalWeight = 0.0f;
|
||||||
for (int j = 0; j < cluster.indices.size(); j++) {
|
for (int j = 0; j < cluster.indices.size(); j++) {
|
||||||
int oldIndex = cluster.indices.at(j);
|
int oldIndex = cluster.indices.at(j);
|
||||||
|
@ -1289,9 +1308,18 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
totalWeight += weight;
|
totalWeight += weight;
|
||||||
for (QMultiHash<int, int>::const_iterator it = extracted.newIndices.constFind(oldIndex);
|
for (QMultiHash<int, int>::const_iterator it = extracted.newIndices.constFind(oldIndex);
|
||||||
it != extracted.newIndices.end() && it.key() == oldIndex; it++) {
|
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
|
// look for an unused slot in the weights vector
|
||||||
|
glm::vec4& weights = extracted.mesh.clusterWeights[it.value()];
|
||||||
for (int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
if (weights[k] == 0.0f) {
|
if (weights[k] == 0.0f) {
|
||||||
extracted.mesh.clusterIndices[it.value()][k] = i;
|
extracted.mesh.clusterIndices[it.value()][k] = i;
|
||||||
|
@ -1303,9 +1331,23 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
}
|
}
|
||||||
if (totalWeight > maxWeight) {
|
if (totalWeight > maxWeight) {
|
||||||
maxWeight = totalWeight;
|
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);
|
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
QVector<int> freeLineage;
|
QVector<int> freeLineage;
|
||||||
int parentIndex;
|
int parentIndex;
|
||||||
float distanceToParent;
|
float distanceToParent;
|
||||||
|
float boneRadius;
|
||||||
glm::mat4 preTransform;
|
glm::mat4 preTransform;
|
||||||
glm::quat preRotation;
|
glm::quat preRotation;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
|
|
Loading…
Reference in a new issue