mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-25 17:29:03 +02:00
Use inheritance type flags. Getting closer to the correct transforms.
This commit is contained in:
parent
3c3cf0b002
commit
3c6fb2914f
2 changed files with 42 additions and 29 deletions
|
@ -135,7 +135,7 @@ bool BlendFace::render(float alpha) {
|
||||||
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
|
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
|
||||||
for (int j = 0; j < coefficients.size(); j++) {
|
for (int j = 0; j < coefficients.size(); j++) {
|
||||||
float coefficient = coefficients[j];
|
float coefficient = coefficients[j];
|
||||||
if (coefficient == 0.0f || i >= mesh.blendshapes.size() || mesh.blendshapes[j].vertices.isEmpty()) {
|
if (coefficient == 0.0f || j >= mesh.blendshapes.size() || mesh.blendshapes[j].vertices.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
|
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
|
||||||
|
|
|
@ -282,12 +282,22 @@ QHash<QByteArray, int> createBlendshapeMap() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 getGlobalTransform(
|
class Transform {
|
||||||
const QMultiHash<qint64, qint64>& parentMap, const QHash<qint64, glm::mat4>& localTransforms, qint64 nodeID) {
|
public:
|
||||||
|
bool inheritScale;
|
||||||
|
glm::mat4 withScale;
|
||||||
|
glm::mat4 withoutScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::mat4 getGlobalTransform(const QMultiHash<qint64, qint64>& parentMap, const QHash<qint64, Transform>& localTransforms,
|
||||||
|
qint64 nodeID, bool forceScale = false) {
|
||||||
|
|
||||||
glm::mat4 globalTransform;
|
glm::mat4 globalTransform;
|
||||||
|
bool useScale = true;
|
||||||
while (nodeID != 0) {
|
while (nodeID != 0) {
|
||||||
globalTransform = localTransforms.value(nodeID) * globalTransform;
|
const Transform& localTransform = localTransforms.value(nodeID);
|
||||||
|
globalTransform = (useScale ? localTransform.withScale : localTransform.withoutScale) * globalTransform;
|
||||||
|
useScale = useScale && localTransform.inheritScale || forceScale;
|
||||||
|
|
||||||
QList<qint64> parentIDs = parentMap.values(nodeID);
|
QList<qint64> parentIDs = parentMap.values(nodeID);
|
||||||
nodeID = 0;
|
nodeID = 0;
|
||||||
|
@ -314,7 +324,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
QVector<ExtractedBlendshape> blendshapes;
|
QVector<ExtractedBlendshape> blendshapes;
|
||||||
QMultiHash<qint64, qint64> parentMap;
|
QMultiHash<qint64, qint64> parentMap;
|
||||||
QMultiHash<qint64, qint64> childMap;
|
QMultiHash<qint64, qint64> childMap;
|
||||||
QHash<qint64, glm::mat4> localTransforms;
|
QHash<qint64, Transform> localTransforms;
|
||||||
QHash<qint64, glm::mat4> transformLinkMatrices;
|
QHash<qint64, glm::mat4> transformLinkMatrices;
|
||||||
QHash<qint64, QByteArray> textureFilenames;
|
QHash<qint64, QByteArray> textureFilenames;
|
||||||
QHash<qint64, qint64> diffuseTextures;
|
QHash<qint64, qint64> diffuseTextures;
|
||||||
|
@ -453,6 +463,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
glm::vec3 preRotation, rotation, postRotation;
|
glm::vec3 preRotation, rotation, postRotation;
|
||||||
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||||
glm::vec3 scalePivot, rotationPivot;
|
glm::vec3 scalePivot, rotationPivot;
|
||||||
|
Transform transform = { true };
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
if (subobject.name == "Properties70") {
|
if (subobject.name == "Properties70") {
|
||||||
foreach (const FBXNode& property, subobject.children) {
|
foreach (const FBXNode& property, subobject.children) {
|
||||||
|
@ -491,18 +502,22 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
scale = glm::vec3(property.properties.at(4).value<double>(),
|
scale = glm::vec3(property.properties.at(4).value<double>(),
|
||||||
property.properties.at(5).value<double>(),
|
property.properties.at(5).value<double>(),
|
||||||
property.properties.at(6).value<double>());
|
property.properties.at(6).value<double>());
|
||||||
|
|
||||||
|
} else if (property.properties.at(0) == "InheritType") {
|
||||||
|
transform.inheritScale = property.properties.at(4) != 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
||||||
localTransforms.insert(object.properties.at(0).value<qint64>(),
|
transform.withoutScale = glm::translate(translation) * glm::translate(rotationPivot) *
|
||||||
glm::translate(translation) * glm::translate(rotationPivot) *
|
|
||||||
glm::mat4_cast(glm::quat(glm::radians(preRotation))) *
|
glm::mat4_cast(glm::quat(glm::radians(preRotation))) *
|
||||||
glm::mat4_cast(glm::quat(glm::radians(rotation))) *
|
glm::mat4_cast(glm::quat(glm::radians(rotation))) *
|
||||||
glm::mat4_cast(glm::quat(glm::radians(postRotation))) * glm::translate(-rotationPivot) *
|
glm::mat4_cast(glm::quat(glm::radians(postRotation))) * glm::translate(-rotationPivot);
|
||||||
glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot));
|
transform.withScale = transform.withoutScale * glm::translate(scalePivot) * glm::scale(scale) *
|
||||||
|
glm::translate(-scalePivot);
|
||||||
|
localTransforms.insert(object.properties.at(0).value<qint64>(), transform);
|
||||||
|
|
||||||
} else if (object.name == "Texture") {
|
} else if (object.name == "Texture") {
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
|
@ -558,10 +573,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
|
|
||||||
// accumulate local transforms
|
// accumulate local transforms
|
||||||
qint64 modelID = parentMap.value(it.key());
|
qint64 modelID = parentMap.value(it.key());
|
||||||
|
glm::mat4 modelTransform = getGlobalTransform(parentMap, localTransforms, modelID);
|
||||||
for (qint64 parentID = parentMap.value(it.key()); parentID != 0; parentID = parentMap.value(parentID)) {
|
|
||||||
mesh.transform = localTransforms.value(parentID) * mesh.transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
// look for textures
|
// look for textures
|
||||||
foreach (qint64 childID, childMap.values(modelID)) {
|
foreach (qint64 childID, childMap.values(modelID)) {
|
||||||
|
@ -578,22 +590,23 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
// look for a limb pivot
|
// look for a limb pivot
|
||||||
mesh.isEye = false;
|
mesh.isEye = false;
|
||||||
foreach (qint64 childID, childMap.values(it.key())) {
|
foreach (qint64 childID, childMap.values(it.key())) {
|
||||||
qint64 clusterID = childMap.value(childID);
|
foreach (qint64 clusterID, childMap.values(childID)) {
|
||||||
if (!transformLinkMatrices.contains(clusterID)) {
|
if (!transformLinkMatrices.contains(clusterID)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
qint64 jointID = childMap.value(clusterID);
|
||||||
|
if (jointID == jointEyeLeftID || jointID == jointEyeRightID) {
|
||||||
|
mesh.isEye = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see http://stackoverflow.com/questions/13566608/loading-skinning-information-from-fbx for a discussion
|
||||||
|
// of skinning information in FBX
|
||||||
|
glm::mat4 jointTransform = getGlobalTransform(parentMap, localTransforms, jointID);
|
||||||
|
mesh.transform = jointTransform * glm::inverse(transformLinkMatrices.value(clusterID)) * modelTransform;
|
||||||
|
|
||||||
|
// extract translation component for pivot
|
||||||
|
mesh.pivot = glm::vec3(jointTransform[3][0], jointTransform[3][1], jointTransform[3][2]);
|
||||||
}
|
}
|
||||||
qint64 jointID = childMap.value(clusterID);
|
|
||||||
if (jointID == jointEyeLeftID || jointID == jointEyeRightID) {
|
|
||||||
mesh.isEye = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// see http://stackoverflow.com/questions/13566608/loading-skinning-information-from-fbx for a discussion
|
|
||||||
// of skinning information in FBX
|
|
||||||
glm::mat4 jointTransform = getGlobalTransform(parentMap, localTransforms, jointID);
|
|
||||||
mesh.transform = jointTransform * glm::inverse(transformLinkMatrices.value(clusterID)) * mesh.transform;
|
|
||||||
|
|
||||||
// extract translation component for pivot
|
|
||||||
mesh.pivot = glm::vec3(jointTransform[3][0], jointTransform[3][1], jointTransform[3][2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.blendshapes.size() > mostBlendshapes) {
|
if (mesh.blendshapes.size() > mostBlendshapes) {
|
||||||
|
@ -606,7 +619,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract translation component for neck pivot
|
// extract translation component for neck pivot
|
||||||
glm::mat4 neckTransform = getGlobalTransform(parentMap, localTransforms, jointNeckID);
|
glm::mat4 neckTransform = getGlobalTransform(parentMap, localTransforms, jointNeckID, true);
|
||||||
geometry.neckPivot = glm::vec3(neckTransform[3][0], neckTransform[3][1], neckTransform[3][2]);
|
geometry.neckPivot = glm::vec3(neckTransform[3][0], neckTransform[3][1], neckTransform[3][2]);
|
||||||
|
|
||||||
return geometry;
|
return geometry;
|
||||||
|
|
Loading…
Reference in a new issue