mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 15:43:08 +02:00
FBXReader: More deterministic loading behavior
This makes iteration over meshes and connections between them deterministic. [QHash](http://doc.qt.io/qt-5/qhash.html#details) and QMultiHash do not guarantee consistent iteration order. This is problematic for the FBXReader because it could result in different behavior each time a model was loaded. Specifically, This was causing a bug with some avatars that contained multiple-bind poses. The bind pose returned to the application from the FBXReader would be different on different runs. This PR doesn't add support for multiple-bind poses, but it does make the choice of which bind pose is chosen deterministic. This non-determinism was the cause of the Mery avatar having "bug-eyes" 1/12 times.
This commit is contained in:
parent
170725418b
commit
5acb088c46
2 changed files with 61 additions and 58 deletions
|
@ -194,7 +194,7 @@ public:
|
|||
glm::vec3 rotationMax; // radians
|
||||
};
|
||||
|
||||
glm::mat4 getGlobalTransform(const QMultiHash<QString, QString>& _connectionParentMap,
|
||||
glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParentMap,
|
||||
const QHash<QString, FBXModel>& models, QString nodeID, bool mixamoHack) {
|
||||
glm::mat4 globalTransform;
|
||||
while (!nodeID.isNull()) {
|
||||
|
@ -246,7 +246,7 @@ public:
|
|||
glm::mat4 transformLink;
|
||||
};
|
||||
|
||||
void appendModelIDs(const QString& parentID, const QMultiHash<QString, QString>& connectionChildMap,
|
||||
void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>& connectionChildMap,
|
||||
QHash<QString, FBXModel>& models, QSet<QString>& remainingModels, QVector<QString>& modelIDs) {
|
||||
if (remainingModels.contains(parentID)) {
|
||||
modelIDs.append(parentID);
|
||||
|
@ -331,7 +331,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIn
|
|||
}
|
||||
}
|
||||
|
||||
QString getTopModelID(const QMultiHash<QString, QString>& connectionParentMap,
|
||||
QString getTopModelID(const QMultiMap<QString, QString>& connectionParentMap,
|
||||
const QHash<QString, FBXModel>& models, const QString& modelID) {
|
||||
QString topID = modelID;
|
||||
forever {
|
||||
|
@ -361,7 +361,7 @@ public:
|
|||
};
|
||||
|
||||
bool checkMaterialsHaveTextures(const QHash<QString, FBXMaterial>& materials,
|
||||
const QHash<QString, QByteArray>& textureFilenames, const QMultiHash<QString, QString>& _connectionChildMap) {
|
||||
const QHash<QString, QByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) {
|
||||
foreach (const QString& materialID, materials.keys()) {
|
||||
foreach (const QString& childID, _connectionChildMap.values(materialID)) {
|
||||
if (textureFilenames.contains(childID)) {
|
||||
|
@ -444,7 +444,7 @@ QByteArray fileOnUrl(const QByteArray& filenameString, const QString& url) {
|
|||
|
||||
FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) {
|
||||
const FBXNode& node = _fbxNode;
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
QMap<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
QHash<QString, int> meshIDsToMeshIndices;
|
||||
QHash<QString, QString> ooChildToParent;
|
||||
|
@ -1293,7 +1293,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
// see if any materials have texture children
|
||||
bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilenames, _connectionChildMap);
|
||||
|
||||
for (QHash<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
||||
for (QMap<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
||||
ExtractedMesh& extracted = it.value();
|
||||
|
||||
extracted.mesh.meshExtents.reset();
|
||||
|
@ -1401,6 +1401,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
joint.bindTransform = cluster.transformLink;
|
||||
joint.bindTransformFoundInCluster = true;
|
||||
|
||||
if (fbxCluster.jointIndex == 63) { // Head
|
||||
qCDebug(modelformat) << "AJT: Head found in cluster, id = " << clusterID;
|
||||
qCDebug(modelformat) << "AJT: trans = " << extractTranslation(cluster.transformLink);
|
||||
}
|
||||
|
||||
// update the bind pose extents
|
||||
glm::vec3 bindTranslation = extractTranslation(geometry.offset * joint.bindTransform);
|
||||
geometry.bindExtents.addPoint(bindTranslation);
|
||||
|
@ -1641,5 +1646,3 @@ FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QStri
|
|||
|
||||
return reader.extractFBXGeometry(mapping, url);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -413,8 +413,8 @@ public:
|
|||
float _lightmapOffset = 0.0f;
|
||||
float _lightmapLevel;
|
||||
|
||||
QMultiHash<QString, QString> _connectionParentMap;
|
||||
QMultiHash<QString, QString> _connectionChildMap;
|
||||
QMultiMap<QString, QString> _connectionParentMap;
|
||||
QMultiMap<QString, QString> _connectionChildMap;
|
||||
|
||||
static glm::vec3 getVec3(const QVariantList& properties, int index);
|
||||
static QVector<glm::vec4> createVec4Vector(const QVector<double>& doubleVector);
|
||||
|
|
Loading…
Reference in a new issue