From 0b2f272abee79143a69a07d499465b180f3ce45e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 2 May 2014 16:26:44 -0700 Subject: [PATCH 01/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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; From 13170ce23f9b0c9dbc74e60a90a2af5161582314 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 3 May 2014 14:48:32 +0200 Subject: [PATCH 13/20] There are 6 assignment-client types right now --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab1212f656..75aa55dacd 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Any target can be terminated with Ctrl-C (SIGINT) in the associated Terminal win This assignment-client will grab one assignment from the domain-server. You can tell the assignment-client what type you want it to be with the `-t` option. You can also run an assignment-client that forks off *n* assignment-clients with the `-n` option. - ./assignment-client -n 5 + ./assignment-client -n 6 To test things out you'll want to run the Interface client. From 2f1e5ad5cac8f375603be4f89d00a4110ef4208b Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 3 May 2014 14:51:16 +0200 Subject: [PATCH 14/20] description update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75aa55dacd..d5fa8de1b4 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ you to run the full stack of the virtual world. In order to set up your own virtual world, you need to set up and run your own local "domain". -The domain-server gives a number different types of assignments to the assignment-client for different features: audio, avatars, voxels, particles, and meta-voxels. +The domain-server gives a number different types of assignments to the assignment-client for different features: audio, avatars, voxels, particles, meta-voxels and models. Follow the instructions in the [build guide](BUILD.md) to build the various components. From eb991b60ce735c35ec2cbab11efa3ef1ecb325c2 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 3 May 2014 09:08:26 -0700 Subject: [PATCH 15/20] =?UTF-8?q?Remove=20dead=20=E2=80=98play=20slaps?= =?UTF-8?q?=E2=80=99=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/avatar/Hand.cpp | 66 ----------------------------------- interface/src/avatar/Hand.h | 3 -- 4 files changed, 71 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index baa82a2f6a..c492af3964 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -336,7 +336,6 @@ Menu::Menu() : SLOT(setFilter(bool))); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index da2585f81a..9a7dda9111 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -340,7 +340,6 @@ namespace MenuOption { const QString Particles = "Particles"; const QString PasteToVoxel = "Paste to Voxel..."; const QString PipelineWarnings = "Show Render Pipeline Warnings"; - const QString PlaySlaps = "Play Slaps"; const QString Preferences = "Preferences..."; const QString Quit = "Quit"; const QString ReloadAllScripts = "Reload All Scripts"; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 0f0df8a484..1ee22d3edf 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -55,76 +55,10 @@ void Hand::simulate(float deltaTime, bool isMine) { } } -void Hand::playSlaps(PalmData& palm, Avatar* avatar) { - // Check for palm collisions - glm::vec3 myPalmPosition = palm.getPosition(); - float palmCollisionDistance = 0.1f; - bool wasColliding = palm.getIsCollidingWithPalm(); - palm.setIsCollidingWithPalm(false); - // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound - for (size_t j = 0; j < avatar->getHand()->getNumPalms(); j++) { - PalmData& otherPalm = avatar->getHand()->getPalms()[j]; - if (!otherPalm.isActive()) { - continue; - } - glm::vec3 otherPalmPosition = otherPalm.getPosition(); - if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { - palm.setIsCollidingWithPalm(true); - if (!wasColliding) { - const float PALM_COLLIDE_VOLUME = 1.f; - const float PALM_COLLIDE_FREQUENCY = 1000.f; - const float PALM_COLLIDE_DURATION_MAX = 0.75f; - const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f; - Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, - PALM_COLLIDE_FREQUENCY, - PALM_COLLIDE_DURATION_MAX, - PALM_COLLIDE_DECAY_PER_SAMPLE); - // If the other person's palm is in motion, move mine downward to show I was hit - const float MIN_VELOCITY_FOR_SLAP = 0.05f; - if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) { - // add slapback here - } - } - } - } -} - // We create a static CollisionList that is recycled for each collision test. const float MAX_COLLISIONS_PER_AVATAR = 32; static CollisionList handCollisions(MAX_COLLISIONS_PER_AVATAR); -void Hand::collideAgainstAvatarOld(Avatar* avatar, bool isMyHand) { - if (!avatar || avatar == _owningAvatar) { - // don't collide with our own hands (that is done elsewhere) - return; - } - float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale(); - for (size_t i = 0; i < getNumPalms(); i++) { - PalmData& palm = getPalms()[i]; - if (!palm.isActive()) { - continue; - } - if (isMyHand && Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { - playSlaps(palm, avatar); - } - - glm::vec3 totalPenetration; - handCollisions.clear(); - if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, handCollisions)) { - for (int j = 0; j < handCollisions.size(); ++j) { - CollisionInfo* collision = handCollisions.getCollision(j); - if (isMyHand) { - totalPenetration = addPenetrations(totalPenetration, collision->_penetration); - } - } - } - if (isMyHand) { - // resolve penetration - palm.addToPosition(-totalPenetration); - } - } -} - void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) { if (!avatar || avatar == _owningAvatar) { // don't collide hands against ourself (that is done elsewhere) diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 1c857a198a..65a7dcb74a 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -58,7 +58,6 @@ public: const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;} const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;} - void collideAgainstAvatarOld(Avatar* avatar, bool isMyHand); void collideAgainstAvatar(Avatar* avatar, bool isMyHand); void collideAgainstOurself(); @@ -80,8 +79,6 @@ private: void renderLeapFingerTrails(); void calculateGeometry(); - - void playSlaps(PalmData& palm, Avatar* avatar); }; #endif // hifi_Hand_h From ab0e8543366a0e6c7e56ffb1252c8bc86946c56a Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 3 May 2014 11:33:39 -0700 Subject: [PATCH 16/20] Removed session UUID from interface title bar --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 285d1c4f1c..666fecaa0a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3132,8 +3132,8 @@ void Application::updateWindowTitle(){ NodeList* nodeList = NodeList::getInstance(); QString username = AccountManager::getInstance().getAccountInfo().getUsername(); - QString title = QString() + (!username.isEmpty() ? username + " " : QString()) + nodeList->getSessionUUID().toString() - + " @ " + nodeList->getDomainHandler().getHostname() + buildVersion; + QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) + + nodeList->getDomainHandler().getHostname() + buildVersion; qDebug("Application title set to: %s", title.toStdString().c_str()); _window->setWindowTitle(title); } From 7f7cd6f65463b8de3fc917d3981917cd85b2a21a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 May 2014 11:15:55 -0700 Subject: [PATCH 17/20] Fix for OS X Fullscreen (closes #2414) --- interface/src/MainWindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/MainWindow.cpp b/interface/src/MainWindow.cpp index 7fddbfffa3..3c2f4a7ca4 100644 --- a/interface/src/MainWindow.cpp +++ b/interface/src/MainWindow.cpp @@ -10,6 +10,7 @@ // #include "MainWindow.h" +#include "Menu.h" #include #include @@ -56,6 +57,10 @@ void MainWindow::changeEvent(QEvent* event) { } else { emit windowShown(true); } + + if (isFullScreen() != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) { + Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, isFullScreen()); + } } else if (event->type() == QEvent::ActivationChange) { if (isActiveWindow()) { emit windowShown(true); From 31b5c39f167f8a12f1334633c26245eb2411b2ae Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 May 2014 11:17:11 -0700 Subject: [PATCH 18/20] Fix warnings --- interface/src/ui/ScriptLineNumberArea.cpp | 2 +- interface/src/ui/ScriptLineNumberArea.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ScriptLineNumberArea.cpp b/interface/src/ui/ScriptLineNumberArea.cpp index 9173c72375..5bb08918b9 100644 --- a/interface/src/ui/ScriptLineNumberArea.cpp +++ b/interface/src/ui/ScriptLineNumberArea.cpp @@ -19,7 +19,7 @@ ScriptLineNumberArea::ScriptLineNumberArea(ScriptEditBox* scriptEditBox) : _scriptEditBox = scriptEditBox; } -QSize ScriptLineNumberArea::sizeHint() { +QSize ScriptLineNumberArea::sizeHint() const { return QSize(_scriptEditBox->lineNumberAreaWidth(), 0); } diff --git a/interface/src/ui/ScriptLineNumberArea.h b/interface/src/ui/ScriptLineNumberArea.h index 75be2048f0..47c540ca0e 100644 --- a/interface/src/ui/ScriptLineNumberArea.h +++ b/interface/src/ui/ScriptLineNumberArea.h @@ -19,7 +19,7 @@ class ScriptLineNumberArea : public QWidget { public: ScriptLineNumberArea(ScriptEditBox* scriptEditBox); - QSize sizeHint(); + QSize sizeHint() const; protected: void paintEvent(QPaintEvent* event); From 7855bf8e2434eca94d3a7b3d9c9e0396378d3d71 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 May 2014 11:35:50 -0700 Subject: [PATCH 19/20] Fix scale issue in editVoxels.js (closes #2776) --- examples/editVoxels.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 453ac28649..8e85341e83 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -331,8 +331,9 @@ function ScaleSelector() { }); this.setScale = function(scale) { this.scale = scale; - this.power = Math.floor(Math.log(scale)); + this.power = Math.ceil(Math.log(scale) * Math.LOG2E); rescaleImport(); + this.update(); } this.show = function(doShow) { @@ -835,7 +836,6 @@ function showPreviewLines() { if (copyScale) { scaleSelector.setScale(intersection.voxel.s); - scaleSelector.update(); } moveTools(); } else { From 1ecf0e3b9d3f4b019163cd3ba95254477c8205da Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 May 2014 11:43:58 -0700 Subject: [PATCH 20/20] Used wrong formula in previous commit --- examples/editVoxels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 8e85341e83..b9f5d925d9 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -331,7 +331,7 @@ function ScaleSelector() { }); this.setScale = function(scale) { this.scale = scale; - this.power = Math.ceil(Math.log(scale) * Math.LOG2E); + this.power = Math.floor(Math.log(scale) / Math.log(2)); rescaleImport(); this.update(); }