From 0b2f272abee79143a69a07d499465b180f3ce45e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 16:26:44 -0700 Subject: [PATCH 01/12] Fix (well, partial fix) for ASCII FBX files exported from Makehuman. --- libraries/fbx/src/FBXReader.cpp | 98 +++++++++++++++++---------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 9389d0abf8..cf34ad6e9c 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -406,7 +406,7 @@ QVariantHash parseMapping(QIODevice* device) { QVector createVec3Vector(const QVector& doubleVector) { QVector values; - for (const double* it = doubleVector.constData(), *end = it + doubleVector.size(); it != end; ) { + for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 3 * 3); it != end; ) { float x = *it++; float y = *it++; float z = *it++; @@ -417,7 +417,7 @@ QVector createVec3Vector(const QVector& doubleVector) { QVector createVec2Vector(const QVector& doubleVector) { QVector values; - for (const double* it = doubleVector.constData(), *end = it + doubleVector.size(); it != end; ) { + for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 2 * 2); it != end; ) { float s = *it++; float t = *it++; values.append(glm::vec2(s, -t)); @@ -432,58 +432,59 @@ glm::mat4 createMat4(const QVector& doubleVector) { doubleVector.at(12), doubleVector.at(13), doubleVector.at(14), doubleVector.at(15)); } -QVector getIntVector(const QVariantList& properties, int index) { - if (index >= properties.size()) { +QVector getIntVector(const FBXNode& node) { + foreach (const FBXNode& child, node.children) { + if (child.name == "a") { + return getIntVector(child); + } + } + if (node.properties.isEmpty()) { return QVector(); } - QVector vector = properties.at(index).value >(); + QVector vector = node.properties.at(0).value >(); if (!vector.isEmpty()) { return vector; } - for (; index < properties.size(); index++) { - vector.append(properties.at(index).toInt()); + for (int i = 0; i < node.properties.size(); i++) { + vector.append(node.properties.at(i).toInt()); } return vector; } -QVector getLongVector(const QVariantList& properties, int index) { - if (index >= properties.size()) { - return QVector(); +QVector getFloatVector(const FBXNode& node) { + foreach (const FBXNode& child, node.children) { + if (child.name == "a") { + return getFloatVector(child); + } } - QVector vector = properties.at(index).value >(); - if (!vector.isEmpty()) { - return vector; - } - for (; index < properties.size(); index++) { - vector.append(properties.at(index).toLongLong()); - } - return vector; -} - -QVector getFloatVector(const QVariantList& properties, int index) { - if (index >= properties.size()) { + if (node.properties.isEmpty()) { return QVector(); } - QVector vector = properties.at(index).value >(); + QVector vector = node.properties.at(0).value >(); if (!vector.isEmpty()) { return vector; } - for (; index < properties.size(); index++) { - vector.append(properties.at(index).toFloat()); + for (int i; i < node.properties.size(); i++) { + vector.append(node.properties.at(i).toFloat()); } return vector; } -QVector getDoubleVector(const QVariantList& properties, int index) { - if (index >= properties.size()) { +QVector getDoubleVector(const FBXNode& node) { + foreach (const FBXNode& child, node.children) { + if (child.name == "a") { + return getDoubleVector(child); + } + } + if (node.properties.isEmpty()) { return QVector(); } - QVector vector = properties.at(index).value >(); + QVector vector = node.properties.at(0).value >(); if (!vector.isEmpty()) { return vector; } - for (; index < properties.size(); index++) { - vector.append(properties.at(index).toDouble()); + for (int i; i < node.properties.size(); i++) { + vector.append(node.properties.at(i).toDouble()); } return vector; } @@ -697,6 +698,9 @@ public: }; void appendIndex(MeshData& data, QVector& indices, int index) { + if (index >= data.polygonIndices.size()) { + return; + } int vertexIndex = data.polygonIndices.at(index); if (vertexIndex < 0) { vertexIndex = -vertexIndex - 1; @@ -749,19 +753,19 @@ ExtractedMesh extractMesh(const FBXNode& object) { QVector textures; foreach (const FBXNode& child, object.children) { if (child.name == "Vertices") { - data.vertices = createVec3Vector(getDoubleVector(child.properties, 0)); + data.vertices = createVec3Vector(getDoubleVector(child)); } else if (child.name == "PolygonVertexIndex") { - data.polygonIndices = getIntVector(child.properties, 0); + data.polygonIndices = getIntVector(child); } else if (child.name == "LayerElementNormal") { data.normalsByVertex = false; foreach (const FBXNode& subdata, child.children) { if (subdata.name == "Normals") { - data.normals = createVec3Vector(getDoubleVector(subdata.properties, 0)); + data.normals = createVec3Vector(getDoubleVector(subdata)); } else if (subdata.name == "NormalsIndex") { - data.normalIndices = getIntVector(subdata.properties, 0); + data.normalIndices = getIntVector(subdata); } else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") { @@ -771,22 +775,22 @@ ExtractedMesh extractMesh(const FBXNode& object) { } else if (child.name == "LayerElementUV" && child.properties.at(0).toInt() == 0) { foreach (const FBXNode& subdata, child.children) { if (subdata.name == "UV") { - data.texCoords = createVec2Vector(getDoubleVector(subdata.properties, 0)); + data.texCoords = createVec2Vector(getDoubleVector(subdata)); } else if (subdata.name == "UVIndex") { - data.texCoordIndices = getIntVector(subdata.properties, 0); + data.texCoordIndices = getIntVector(subdata); } } } else if (child.name == "LayerElementMaterial") { foreach (const FBXNode& subdata, child.children) { if (subdata.name == "Materials") { - materials = getIntVector(subdata.properties, 0); + materials = getIntVector(subdata); } } } else if (child.name == "LayerElementTexture") { foreach (const FBXNode& subdata, child.children) { if (subdata.name == "TextureId") { - textures = getIntVector(subdata.properties, 0); + textures = getIntVector(subdata); } } } @@ -797,7 +801,7 @@ ExtractedMesh extractMesh(const FBXNode& object) { QHash, int> materialTextureParts; for (int beginIndex = 0; beginIndex < data.polygonIndices.size(); polygonIndex++) { int endIndex = beginIndex; - while (data.polygonIndices.at(endIndex++) >= 0); + while (endIndex < data.polygonIndices.size() && data.polygonIndices.at(endIndex++) >= 0); QPair materialTexture((polygonIndex < materials.size()) ? materials.at(polygonIndex) : 0, (polygonIndex < textures.size()) ? textures.at(polygonIndex) : 0); @@ -820,7 +824,7 @@ ExtractedMesh extractMesh(const FBXNode& object) { appendIndex(data, part.triangleIndices, beginIndex); appendIndex(data, part.triangleIndices, nextIndex++); appendIndex(data, part.triangleIndices, nextIndex); - if (data.polygonIndices.at(nextIndex) < 0) { + if (nextIndex >= data.polygonIndices.size() || data.polygonIndices.at(nextIndex) < 0) { break; } } @@ -835,13 +839,13 @@ FBXBlendshape extractBlendshape(const FBXNode& object) { FBXBlendshape blendshape; foreach (const FBXNode& data, object.children) { if (data.name == "Indexes") { - blendshape.indices = getIntVector(data.properties, 0); + blendshape.indices = getIntVector(data); } else if (data.name == "Vertices") { - blendshape.vertices = createVec3Vector(getDoubleVector(data.properties, 0)); + blendshape.vertices = createVec3Vector(getDoubleVector(data)); } else if (data.name == "Normals") { - blendshape.normals = createVec3Vector(getDoubleVector(data.properties, 0)); + blendshape.normals = createVec3Vector(getDoubleVector(data)); } } return blendshape; @@ -1262,13 +1266,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) Cluster cluster; foreach (const FBXNode& subobject, object.children) { if (subobject.name == "Indexes") { - cluster.indices = getIntVector(subobject.properties, 0); + cluster.indices = getIntVector(subobject); } else if (subobject.name == "Weights") { - cluster.weights = getDoubleVector(subobject.properties, 0); + cluster.weights = getDoubleVector(subobject); } else if (subobject.name == "TransformLink") { - QVector values = getDoubleVector(subobject.properties, 0); + QVector values = getDoubleVector(subobject); cluster.transformLink = createMat4(values); } } @@ -1290,7 +1294,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) AnimationCurve curve; foreach (const FBXNode& subobject, object.children) { if (subobject.name == "KeyValueFloat") { - curve.values = getFloatVector(subobject.properties, 0); + curve.values = getFloatVector(subobject); } } animationCurves.insert(getID(object.properties), curve); From 6f3b3acc86fd7e2736701e3ae319211ff3f24a8b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 16:27:39 -0700 Subject: [PATCH 02/12] Remove pushback entirely for other avatars. --- interface/src/Application.cpp | 36 ----------------------------------- 1 file changed, 36 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7fc241daf8..4e7db1fd0c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -555,42 +555,6 @@ void Application::paintGL() { _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition()); _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) { - glm::vec3 planeNormal = _myCamera.getTargetRotation() * IDENTITY_FRONT; - const float BASE_PUSHBACK_RADIUS = 0.25f; - float pushbackRadius = _myCamera.getNearClip() + _myAvatar->getScale() * BASE_PUSHBACK_RADIUS; - glm::vec4 plane(planeNormal, -glm::dot(planeNormal, _myCamera.getTargetPosition()) - pushbackRadius); - - // push camera out of any intersecting avatars - foreach (const AvatarSharedPointer& avatarData, _avatarManager.getAvatarHash()) { - Avatar* avatar = static_cast(avatarData.data()); - if (avatar->isMyAvatar()) { - continue; - } - if (glm::distance(avatar->getPosition(), _myCamera.getTargetPosition()) > - avatar->getBoundingRadius() + pushbackRadius) { - continue; - } - float angle = angleBetween(avatar->getPosition() - _myCamera.getTargetPosition(), planeNormal); - if (angle > PI_OVER_TWO) { - continue; - } - float scale = 1.0f - angle / PI_OVER_TWO; - scale = qMin(1.0f, scale * 2.5f); - static CollisionList collisions(64); - collisions.clear(); - if (!avatar->findPlaneCollisions(plane, collisions)) { - continue; - } - for (int i = 0; i < collisions.size(); i++) { - pushback = qMax(pushback, glm::length(collisions.getCollision(i)->_penetration) * scale); - } - } - const float MAX_PUSHBACK = 0.35f; - pushback = qMin(pushback, MAX_PUSHBACK * _myAvatar->getScale()); - const float BASE_PUSHBACK_FOCAL_LENGTH = 0.5f; - pushbackFocalLength = BASE_PUSHBACK_FOCAL_LENGTH * _myAvatar->getScale(); - } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition()); From 4c49d00683699dda8178d7473e915618a6635835 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 17:01:07 -0700 Subject: [PATCH 03/12] Scale adjustment for Makehuman models. --- interface/src/ModelUploader.cpp | 2 +- libraries/fbx/src/FBXReader.cpp | 8 +++++++- libraries/fbx/src/FBXReader.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 83851ded8e..25be8fa649 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -153,7 +153,7 @@ bool ModelUploader::zip() { // mixamo/autodesk defaults if (!mapping.contains(SCALE_FIELD)) { - mapping.insert(SCALE_FIELD, 15.0); + mapping.insert(SCALE_FIELD, geometry.author == "www.makehuman.org" ? 150.0 : 15.0); } QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); if (!joints.contains("jointEyeLeft")) { diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index cf34ad6e9c..385f45e323 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1020,7 +1020,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) foreach (const FBXNode& object, child.children) { if (object.name == "SceneInfo") { foreach (const FBXNode& subobject, object.children) { - if (subobject.name == "Properties70") { + if (subobject.name == "MetaData") { + foreach (const FBXNode& subsubobject, subobject.children) { + if (subsubobject.name == "Author") { + geometry.author = subsubobject.properties.at(0).toString(); + } + } + } else if (subobject.name == "Properties70") { foreach (const FBXNode& subsubobject, subobject.children) { if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 && subsubobject.properties.at(0) == "Original|ApplicationName") { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index af00e35398..a4b04825ef 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -177,6 +177,7 @@ public: class FBXGeometry { public: + QString author; QString applicationName; ///< the name of the application that generated the model QVector joints; From b458cd1297f3bec28adf391d451ebf0152038960 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 17:29:38 -0700 Subject: [PATCH 04/12] Default joint mappings for Makehuman models. --- interface/src/ModelUploader.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 25be8fa649..0ffd725716 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -157,10 +157,10 @@ bool ModelUploader::zip() { } QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); if (!joints.contains("jointEyeLeft")) { - joints.insert("jointEyeLeft", "LeftEye"); + joints.insert("jointEyeLeft", geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye"); } if (!joints.contains("jointEyeRight")) { - joints.insert("jointEyeRight", "RightEye"); + joints.insert("jointEyeRight", geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye"); } if (!joints.contains("jointNeck")) { joints.insert("jointNeck", "Neck"); @@ -172,7 +172,8 @@ bool ModelUploader::zip() { joints.insert("jointLean", "Spine"); } if (!joints.contains("jointHead")) { - joints.insert("jointHead", geometry.applicationName == "mixamo.com" ? "HeadTop_End" : "HeadEnd"); + const char* topName = (geometry.applicationName == "mixamo.com") ? "HeadTop_End" : "HeadEnd"; + joints.insert("jointHead", geometry.jointIndices.contains(topName) ? topName : "Head"); } if (!joints.contains("jointLeftHand")) { joints.insert("jointLeftHand", "LeftHand"); From c08dfc90c3a661024eb78db0faa63397afcedf42 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 17:46:11 -0700 Subject: [PATCH 05/12] Add a hack to fix normals on Makehuman exports. --- libraries/fbx/src/FBXReader.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 385f45e323..0bf203be02 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -760,6 +760,7 @@ ExtractedMesh extractMesh(const FBXNode& object) { } else if (child.name == "LayerElementNormal") { data.normalsByVertex = false; + bool indexToDirect = false; foreach (const FBXNode& subdata, child.children) { if (subdata.name == "Normals") { data.normals = createVec3Vector(getDoubleVector(subdata)); @@ -767,11 +768,17 @@ ExtractedMesh extractMesh(const FBXNode& object) { } else if (subdata.name == "NormalsIndex") { data.normalIndices = getIntVector(subdata); - } else if (subdata.name == "MappingInformationType" && - subdata.properties.at(0) == "ByVertice") { + } else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") { data.normalsByVertex = true; + + } else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == "IndexToDirect") { + indexToDirect = true; } } + if (indexToDirect && data.normalIndices.isEmpty()) { + // hack to work around wacky Makehuman exports + data.normalsByVertex = true; + } } else if (child.name == "LayerElementUV" && child.properties.at(0).toInt() == 0) { foreach (const FBXNode& subdata, child.children) { if (subdata.name == "UV") { From a1eeef3febad3ab69ceb77e06f0db9febbabf7fc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 17:52:52 -0700 Subject: [PATCH 06/12] Out-of-bounds check. --- libraries/fbx/src/FBXReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 0bf203be02..ea97c2e789 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -715,7 +715,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { } else { int normalIndex = data.normalIndices.at(data.normalsByVertex ? vertexIndex : index); - if (normalIndex >= 0) { + if (normalIndex >= 0 && normalIndex < data.normals.size()) { normal = data.normals.at(normalIndex); } } @@ -726,7 +726,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { } } else { int texCoordIndex = data.texCoordIndices.at(index); - if (texCoordIndex >= 0) { + if (texCoordIndex >= 0 && texCoordIndex < data.texCoords.size()) { vertex.texCoord = data.texCoords.at(texCoordIndex); } } From 0c8b3eaf1aa0c092b8d98a53a30193f2f0245e09 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 17:56:23 -0700 Subject: [PATCH 07/12] Yet another check. --- libraries/fbx/src/FBXReader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index ea97c2e789..f3c5133eb3 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -705,6 +705,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { if (vertexIndex < 0) { vertexIndex = -vertexIndex - 1; } + vertexIndex = qMin(vertexIndex, data.vertices.size() - 1); Vertex vertex; vertex.originalIndex = vertexIndex; From 3e8b5c8714cef10f5d5f637d9a4d116b617d2f80 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 18:03:54 -0700 Subject: [PATCH 08/12] Let's try that again. --- libraries/fbx/src/FBXReader.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index f3c5133eb3..a5538f8c28 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -705,17 +705,17 @@ void appendIndex(MeshData& data, QVector& indices, int index) { if (vertexIndex < 0) { vertexIndex = -vertexIndex - 1; } - vertexIndex = qMin(vertexIndex, data.vertices.size() - 1); - Vertex vertex; vertex.originalIndex = vertexIndex; glm::vec3 normal; - if (data.normalIndices.isEmpty()) { - normal = data.normals.at(data.normalsByVertex ? vertexIndex : index); - - } else { - int normalIndex = data.normalIndices.at(data.normalsByVertex ? vertexIndex : index); + int normalIndex = data.normalsByVertex ? vertexIndex : index; + if (data.normalIndices.isEmpty()) { + if (normalIndex < data.normals.size()) { + normal = data.normals.at(normalIndex); + } + } else if (normalIndex < data.normalIndices.size()) { + normalIndex = data.normalIndices.at(normalIndex); if (normalIndex >= 0 && normalIndex < data.normals.size()) { normal = data.normals.at(normalIndex); } @@ -725,7 +725,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { if (index < data.texCoords.size()) { vertex.texCoord = data.texCoords.at(index); } - } else { + } else if (index < data.texCoordIndices.size()) { int texCoordIndex = data.texCoordIndices.at(index); if (texCoordIndex >= 0 && texCoordIndex < data.texCoords.size()) { vertex.texCoord = data.texCoords.at(texCoordIndex); From 8ec03979da56e04d6dcc42d77b9ecbade6839228 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 18:14:17 -0700 Subject: [PATCH 09/12] OK, one more try. --- libraries/fbx/src/FBXReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index a5538f8c28..be6846d26a 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -738,7 +738,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { indices.append(newIndex); data.indices.insert(vertex, newIndex); data.extracted.newIndices.insert(vertexIndex, newIndex); - data.extracted.mesh.vertices.append(data.vertices.at(vertexIndex)); + data.extracted.mesh.vertices.append(data.vertices.at(qMin(vertexIndex, data.vertices.size() - 1))); data.extracted.mesh.normals.append(normal); data.extracted.mesh.texCoords.append(vertex.texCoord); From 9959d8d73fd1e10feb644f2fac3568a1be432408 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 19:06:44 -0700 Subject: [PATCH 10/12] OK, this time for sure. --- libraries/fbx/src/FBXReader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index be6846d26a..40a917b06d 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -707,6 +707,11 @@ void appendIndex(MeshData& data, QVector& indices, int index) { } Vertex vertex; vertex.originalIndex = vertexIndex; + + glm::vec3 position; + if (vertexIndex < data.vertices.size()) { + position = data.vertices.at(vertexIndex); + } glm::vec3 normal; int normalIndex = data.normalsByVertex ? vertexIndex : index; @@ -738,7 +743,7 @@ void appendIndex(MeshData& data, QVector& indices, int index) { indices.append(newIndex); data.indices.insert(vertex, newIndex); data.extracted.newIndices.insert(vertexIndex, newIndex); - data.extracted.mesh.vertices.append(data.vertices.at(qMin(vertexIndex, data.vertices.size() - 1))); + data.extracted.mesh.vertices.append(position); data.extracted.mesh.normals.append(normal); data.extracted.mesh.texCoords.append(vertex.texCoord); From 9e6b29951d30b37c0c3bed8bc4f1d610f25f3439 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 19:14:40 -0700 Subject: [PATCH 11/12] Whoops! --- libraries/fbx/src/FBXReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 40a917b06d..a21ed2627a 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -464,7 +464,7 @@ QVector getFloatVector(const FBXNode& node) { if (!vector.isEmpty()) { return vector; } - for (int i; i < node.properties.size(); i++) { + for (int i = 0; i < node.properties.size(); i++) { vector.append(node.properties.at(i).toFloat()); } return vector; @@ -483,7 +483,7 @@ QVector getDoubleVector(const FBXNode& node) { if (!vector.isEmpty()) { return vector; } - for (int i; i < node.properties.size(); i++) { + for (int i = 0; i < node.properties.size(); i++) { vector.append(node.properties.at(i).toDouble()); } return vector; From 3a4dfb92f65cd384031afbb1c2df5f1eed891d01 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 19:37:42 -0700 Subject: [PATCH 12/12] Let's try using the neck parent rotation, rather than the neck, to fix separate heads. --- interface/src/avatar/FaceModel.cpp | 8 ++++---- interface/src/renderer/Model.cpp | 11 +++++++++++ interface/src/renderer/Model.h | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 709a9fc79d..90e596bde5 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -29,11 +29,11 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) { neckPosition = owningAvatar->getPosition(); } setTranslation(neckPosition); - glm::quat neckRotation; - if (!owningAvatar->getSkeletonModel().getNeckRotation(neckRotation)) { - neckRotation = owningAvatar->getOrientation(); + glm::quat neckParentRotation; + if (!owningAvatar->getSkeletonModel().getNeckParentRotation(neckParentRotation)) { + neckParentRotation = owningAvatar->getOrientation(); } - setRotation(neckRotation); + setRotation(neckParentRotation); const float MODEL_SCALE = 0.0006f; setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 5c06d2fcf3..a177783955 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -434,6 +434,17 @@ bool Model::getNeckRotation(glm::quat& neckRotation) const { return isActive() && getJointRotation(_geometry->getFBXGeometry().neckJointIndex, neckRotation); } +bool Model::getNeckParentRotation(glm::quat& neckParentRotation) const { + if (!isActive()) { + return false; + } + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + if (geometry.neckJointIndex == -1) { + return false; + } + return getJointRotation(geometry.joints.at(geometry.neckJointIndex).parentIndex, neckParentRotation); +} + bool Model::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { if (!isActive()) { return false; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 14589d1464..ae2bcd79b8 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -132,6 +132,10 @@ public: /// \return whether or not the neck was found bool getNeckRotation(glm::quat& neckRotation) const; + /// Returns the rotation of the neck joint's parent. + /// \return whether or not the neck was found + bool getNeckParentRotation(glm::quat& neckRotation) const; + /// Retrieve the positions of up to two eye meshes. /// \return whether or not both eye meshes were found bool getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const;