Merge pull request #1351 from ey6es/master

Fix for segfault on Linux exit; enable alpha testing for models; allow coefficients to apply multiple blendshapes.
This commit is contained in:
ZappoMan 2013-12-10 18:34:02 -08:00
commit 8934d73de3
4 changed files with 45 additions and 19 deletions

View file

@ -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();

View file

@ -29,10 +29,13 @@ int main(int argc, const char * argv[]) {
QCoreApplication::addLibraryPath(QT_RELEASE_PLUGIN_PATH);
#endif
Application app(argc, const_cast<char**>(argv), startup_time);
int exitCode;
{
Application app(argc, const_cast<char**>(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;
}

View file

@ -582,6 +582,7 @@ class ExtractedMesh {
public:
FBXMesh mesh;
QMultiHash<int, int> newIndices;
QVector<QHash<int, int> > blendshapeIndexMaps;
};
class MeshData {
@ -780,7 +781,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
QVector<QString> jointRightFingertipIDs(jointRightFingertipNames.size());
QVariantHash blendshapeMappings = mapping.value("bs").toHash();
QHash<QByteArray, QPair<int, float> > blendshapeIndices;
typedef QPair<int, float> WeightedIndex;
QMultiHash<QByteArray, WeightedIndex> 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<QVariant> mappings = blendshapeMappings.values(blendshapeName);
if (mappings.isEmpty()) {
blendshapeIndices.insert(blendshapeName, QPair<int, float>(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<int, float>(i, blendshapeMapping.at(1).toFloat()));
WeightedIndex(i, blendshapeMapping.at(1).toFloat()));
}
}
}
QHash<QString, QPair<int, float> > blendshapeChannelIndices;
QMultiHash<QString, WeightedIndex> 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<int, float> 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<int, int>::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<int, int>& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first];
for (int i = 0; i < extracted.blendshape.indices.size(); i++) {
int oldIndex = extracted.blendshape.indices.at(i);
for (QMultiHash<int, int>::const_iterator it = extractedMesh.newIndices.constFind(oldIndex);
it != extractedMesh.newIndices.constEnd() && it.key() == oldIndex; it++) {
QHash<int, int>::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;
}
}
}
}
}

View file

@ -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);