mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 15:52:14 +02:00
Merge pull request #12178 from ctrlaltdavid/21694
Support FBX files that have nodes with non-XYZ rotation order
This commit is contained in:
commit
b17913366a
1 changed files with 62 additions and 3 deletions
|
@ -148,6 +148,59 @@ glm::vec3 parseVec3(const QString& string) {
|
|||
return value;
|
||||
}
|
||||
|
||||
enum RotationOrder {
|
||||
OrderXYZ = 0,
|
||||
OrderXZY,
|
||||
OrderYZX,
|
||||
OrderYXZ,
|
||||
OrderZXY,
|
||||
OrderZYX,
|
||||
OrderSphericXYZ
|
||||
};
|
||||
|
||||
bool haveReportedUnhandledRotationOrder = false; // Report error only once per FBX file.
|
||||
|
||||
glm::vec3 convertRotationToXYZ(int rotationOrder, const glm::vec3& rotation) {
|
||||
// Convert rotation with given rotation order to have order XYZ.
|
||||
if (rotationOrder == OrderXYZ) {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
glm::quat xyzRotation;
|
||||
|
||||
switch (rotationOrder) {
|
||||
case OrderXZY:
|
||||
xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))
|
||||
* (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))));
|
||||
break;
|
||||
case OrderYZX:
|
||||
xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0)))
|
||||
* (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))));
|
||||
break;
|
||||
case OrderYXZ:
|
||||
xyzRotation = glm::quat(glm::radians(glm::vec3(0, 0, rotation.z)))
|
||||
* (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))));
|
||||
break;
|
||||
case OrderZXY:
|
||||
xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))
|
||||
* (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))));
|
||||
break;
|
||||
case OrderZYX:
|
||||
xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0)))
|
||||
* (glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))));
|
||||
break;
|
||||
default:
|
||||
// FIXME: Handle OrderSphericXYZ.
|
||||
if (!haveReportedUnhandledRotationOrder) {
|
||||
qCDebug(modelformat) << "ERROR: Unhandled rotation order in FBX file:" << rotationOrder;
|
||||
haveReportedUnhandledRotationOrder = true;
|
||||
}
|
||||
return rotation;
|
||||
}
|
||||
|
||||
return glm::degrees(safeEulerAngles(xyzRotation));
|
||||
}
|
||||
|
||||
QString processID(const QString& id) {
|
||||
// Blender (at least) prepends a type to the ID, so strip it out
|
||||
return id.mid(id.lastIndexOf(':') + 1);
|
||||
|
@ -630,6 +683,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
glm::vec3 ambientColor;
|
||||
QString hifiGlobalNodeID;
|
||||
unsigned int meshIndex = 0;
|
||||
haveReportedUnhandledRotationOrder = false;
|
||||
foreach (const FBXNode& child, node.children) {
|
||||
|
||||
if (child.name == "FBXHeaderExtension") {
|
||||
|
@ -731,6 +785,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
glm::vec3 translation;
|
||||
// NOTE: the euler angles as supplied by the FBX file are in degrees
|
||||
glm::vec3 rotationOffset;
|
||||
int rotationOrder = OrderXYZ; // Default rotation order set in "Definitions" node is assumed to be XYZ.
|
||||
glm::vec3 preRotation, rotation, postRotation;
|
||||
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 scalePivot, rotationPivot, scaleOffset;
|
||||
|
@ -764,6 +819,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
index = 4;
|
||||
}
|
||||
if (properties) {
|
||||
static const QVariant ROTATION_ORDER = QByteArray("RotationOrder");
|
||||
static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation");
|
||||
static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation");
|
||||
static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling");
|
||||
|
@ -790,6 +846,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
if (childProperty == LCL_TRANSLATION) {
|
||||
translation = getVec3(property.properties, index);
|
||||
|
||||
} else if (childProperty == ROTATION_ORDER) {
|
||||
rotationOrder = property.properties.at(index).toInt();
|
||||
|
||||
} else if (childProperty == ROTATION_OFFSET) {
|
||||
rotationOffset = getVec3(property.properties, index);
|
||||
|
||||
|
@ -797,13 +856,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
rotationPivot = getVec3(property.properties, index);
|
||||
|
||||
} else if (childProperty == PRE_ROTATION) {
|
||||
preRotation = getVec3(property.properties, index);
|
||||
preRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
|
||||
|
||||
} else if (childProperty == LCL_ROTATION) {
|
||||
rotation = getVec3(property.properties, index);
|
||||
rotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
|
||||
|
||||
} else if (childProperty == POST_ROTATION) {
|
||||
postRotation = getVec3(property.properties, index);
|
||||
postRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
|
||||
|
||||
} else if (childProperty == SCALING_PIVOT) {
|
||||
scalePivot = getVec3(property.properties, index);
|
||||
|
|
Loading…
Reference in a new issue