diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a9ff0a3681..2a8e7f4651 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -235,6 +235,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : } Application::~Application() { + // make sure we don't call the idle timer any more + delete idleTimer; + // ask the audio thread to quit and wait until it is done _audio.thread()->quit(); _audio.thread()->wait(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c1d9bd778d..31468f1320 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -29,10 +29,13 @@ int main(int argc, const char * argv[]) { QCoreApplication::addLibraryPath(QT_RELEASE_PLUGIN_PATH); #endif - Application app(argc, const_cast(argv), startup_time); + int exitCode; + { + Application app(argc, const_cast(argv), startup_time); - qDebug( "Created QT Application.\n" ); - int exitCode = app.exec(); + qDebug( "Created QT Application.\n" ); + exitCode = app.exec(); + } qDebug("Normal exit.\n"); return exitCode; } diff --git a/interface/src/renderer/FBXReader.cpp b/interface/src/renderer/FBXReader.cpp index 61c0ae775b..63e3afc8cf 100644 --- a/interface/src/renderer/FBXReader.cpp +++ b/interface/src/renderer/FBXReader.cpp @@ -582,6 +582,7 @@ class ExtractedMesh { public: FBXMesh mesh; QMultiHash newIndices; + QVector > blendshapeIndexMaps; }; class MeshData { @@ -780,7 +781,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) QVector jointRightFingertipIDs(jointRightFingertipNames.size()); QVariantHash blendshapeMappings = mapping.value("bs").toHash(); - QHash > blendshapeIndices; + typedef QPair WeightedIndex; + QMultiHash blendshapeIndices; for (int i = 0;; i++) { QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i]; if (blendshapeName.isEmpty()) { @@ -788,16 +790,16 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } QList mappings = blendshapeMappings.values(blendshapeName); if (mappings.isEmpty()) { - blendshapeIndices.insert(blendshapeName, QPair(i, 1.0f)); + blendshapeIndices.insert(blendshapeName, WeightedIndex(i, 1.0f)); } else { foreach (const QVariant& mapping, mappings) { QVariantList blendshapeMapping = mapping.toList(); blendshapeIndices.insert(blendshapeMapping.at(0).toByteArray(), - QPair(i, blendshapeMapping.at(1).toFloat())); + WeightedIndex(i, blendshapeMapping.at(1).toFloat())); } } } - QHash > blendshapeChannelIndices; + QMultiHash blendshapeChannelIndices; foreach (const FBXNode& child, node.children) { if (child.name == "Objects") { @@ -1033,7 +1035,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) // try everything after the dot name = name.mid(name.lastIndexOf('.') + 1); } - blendshapeChannelIndices.insert(getID(object.properties), blendshapeIndices.value(name)); + QString id = getID(object.properties); + foreach (const WeightedIndex& index, blendshapeIndices.values(name)) { + blendshapeChannelIndices.insert(id, index); + } } } } @@ -1059,20 +1064,30 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) // assign the blendshapes to their corresponding meshes foreach (const ExtractedBlendshape& extracted, blendshapes) { QString blendshapeChannelID = parentMap.value(extracted.id); - QPair index = blendshapeChannelIndices.value(blendshapeChannelID); QString blendshapeID = parentMap.value(blendshapeChannelID); QString meshID = parentMap.value(blendshapeID); ExtractedMesh& extractedMesh = meshes[meshID]; - extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1)); - FBXBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first]; - for (int i = 0; i < extracted.blendshape.indices.size(); i++) { - int oldIndex = extracted.blendshape.indices.at(i); - for (QMultiHash::const_iterator it = extractedMesh.newIndices.constFind(oldIndex); - it != extractedMesh.newIndices.constEnd() && it.key() == oldIndex; it++) { - blendshape.indices.append(it.value()); - blendshape.vertices.append(extracted.blendshape.vertices.at(i) * index.second); - blendshape.normals.append(extracted.blendshape.normals.at(i) * index.second); - } + foreach (const WeightedIndex& index, blendshapeChannelIndices.values(blendshapeChannelID)) { + extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1)); + extractedMesh.blendshapeIndexMaps.resize(extractedMesh.mesh.blendshapes.size()); + FBXBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first]; + QHash& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first]; + for (int i = 0; i < extracted.blendshape.indices.size(); i++) { + int oldIndex = extracted.blendshape.indices.at(i); + for (QMultiHash::const_iterator it = extractedMesh.newIndices.constFind(oldIndex); + it != extractedMesh.newIndices.constEnd() && it.key() == oldIndex; it++) { + QHash::iterator blendshapeIndex = blendshapeIndexMap.find(it.value()); + if (blendshapeIndex == blendshapeIndexMap.end()) { + blendshapeIndexMap.insert(it.value(), blendshape.indices.size()); + blendshape.indices.append(it.value()); + blendshape.vertices.append(extracted.blendshape.vertices.at(i) * index.second); + blendshape.normals.append(extracted.blendshape.normals.at(i) * index.second); + } else { + blendshape.vertices[*blendshapeIndex] += extracted.blendshape.vertices.at(i) * index.second; + blendshape.normals[*blendshapeIndex] += extracted.blendshape.normals.at(i) * index.second; + } + } + } } } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index c0403b6d71..9660c05095 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -263,6 +263,9 @@ bool Model::render(float alpha) { glDisable(GL_COLOR_MATERIAL); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); + for (int i = 0; i < networkMeshes.size(); i++) { const NetworkMesh& networkMesh = networkMeshes.at(i); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, networkMesh.indexBufferID); @@ -443,6 +446,8 @@ bool Model::render(float alpha) { glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_ALPHA_TEST); + // bind with 0 to switch back to normal operation glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);