mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 00:13:53 +02:00
Support for the 3ds Max object offset feature
FBXReader now supports the GeometricTranslation, GeometricRotation and GeometricScaling FBX fields. These offsets are applied directly to the mesh vertices, as they are never animated and the rest of our rendering and animation system would have difficulty supporting them otherwise.
This commit is contained in:
parent
881e0cba11
commit
e96676fea4
2 changed files with 47 additions and 1 deletions
|
@ -202,6 +202,11 @@ public:
|
|||
|
||||
glm::vec3 rotationMin; // radians
|
||||
glm::vec3 rotationMax; // radians
|
||||
|
||||
bool hasGeometricOffset;
|
||||
glm::vec3 geometricTranslation;
|
||||
glm::quat geometricRotation;
|
||||
glm::vec3 geometricScaling;
|
||||
};
|
||||
|
||||
glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParentMap,
|
||||
|
@ -639,6 +644,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
glm::vec3 scalePivot, rotationPivot, scaleOffset;
|
||||
bool rotationMinX = false, rotationMinY = false, rotationMinZ = false;
|
||||
bool rotationMaxX = false, rotationMaxY = false, rotationMaxZ = false;
|
||||
|
||||
// local offset transforms from 3ds max
|
||||
bool hasGeometricOffset = false;
|
||||
glm::vec3 geometricTranslation;
|
||||
glm::vec3 geometricScaling(1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 geometricRotation;
|
||||
|
||||
glm::vec3 rotationMin, rotationMax;
|
||||
FBXModel model = { name, -1, glm::vec3(), glm::mat4(), glm::quat(), glm::quat(), glm::quat(),
|
||||
glm::mat4(), glm::vec3(), glm::vec3()};
|
||||
|
@ -712,6 +724,15 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
|
||||
} else if (property.properties.at(0) == "RotationMaxZ") {
|
||||
rotationMaxZ = property.properties.at(index).toBool();
|
||||
} else if (property.properties.at(0) == "GeometricTranslation") {
|
||||
geometricTranslation = getVec3(property.properties, index);
|
||||
hasGeometricOffset = true;
|
||||
} else if (property.properties.at(0) == "GeometricRotation") {
|
||||
geometricRotation = getVec3(property.properties, index);
|
||||
hasGeometricOffset = true;
|
||||
} else if (property.properties.at(0) == "GeometricScaling") {
|
||||
geometricScaling = getVec3(property.properties, index);
|
||||
hasGeometricOffset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -768,8 +789,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f));
|
||||
model.rotationMax = glm::radians(glm::vec3(rotationMaxX ? rotationMax.x : 180.0f,
|
||||
rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f));
|
||||
models.insert(getID(object.properties), model);
|
||||
|
||||
model.hasGeometricOffset = hasGeometricOffset;
|
||||
model.geometricTranslation = geometricTranslation;
|
||||
model.geometricRotation = glm::quat(glm::radians(geometricRotation));
|
||||
model.geometricScaling = geometricScaling;
|
||||
|
||||
models.insert(getID(object.properties), model);
|
||||
} else if (object.name == "Texture") {
|
||||
TextureParam tex;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
|
@ -1286,7 +1312,14 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
joint.postTransform = model.postTransform;
|
||||
joint.rotationMin = model.rotationMin;
|
||||
joint.rotationMax = model.rotationMax;
|
||||
|
||||
joint.hasGeometricOffset = model.hasGeometricOffset;
|
||||
joint.geometricTranslation = model.geometricTranslation;
|
||||
joint.geometricRotation = model.geometricRotation;
|
||||
joint.geometricScaling = model.geometricScaling;
|
||||
|
||||
glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation;
|
||||
|
||||
if (joint.parentIndex == -1) {
|
||||
joint.transform = geometry.offset * glm::translate(joint.translation) * joint.preTransform *
|
||||
glm::mat4_cast(combinedRotation) * joint.postTransform;
|
||||
|
@ -1602,6 +1635,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
points.push_back(extractTranslation(vertexTransform) * clusterScale);
|
||||
}
|
||||
|
||||
// Apply geometric offset, if present, by transforming the vertices directly
|
||||
if (joint.hasGeometricOffset) {
|
||||
glm::mat4 geometricOffset = createMatFromScaleQuatAndPos(joint.geometricScaling, joint.geometricRotation, joint.geometricTranslation);
|
||||
for (int i = 0; i < extracted.mesh.vertices.size(); i++) {
|
||||
extracted.mesh.vertices[i] = transformPoint(geometricOffset, extracted.mesh.vertices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
||||
|
||||
|
|
|
@ -88,6 +88,12 @@ public:
|
|||
QString name;
|
||||
bool isSkeletonJoint;
|
||||
bool bindTransformFoundInCluster;
|
||||
|
||||
// geometric offset is applied in local space but does NOT affect children.
|
||||
bool hasGeometricOffset;
|
||||
glm::vec3 geometricTranslation;
|
||||
glm::quat geometricRotation;
|
||||
glm::vec3 geometricScaling;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue