Map the blendshapes by name.

This commit is contained in:
Andrzej Kapolka 2013-09-19 15:48:33 -07:00
parent 116a4e0bad
commit fff10375a9
2 changed files with 72 additions and 12 deletions

View file

@ -55,7 +55,7 @@ bool BlendFace::render(float alpha) {
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
for (int i = 0; i < coefficients.size(); i++) {
float coefficient = coefficients[i];
if (coefficient == 0.0f || i >= _geometry.blendshapes.size()) {
if (coefficient == 0.0f || i >= _geometry.blendshapes.size() || _geometry.blendshapes[i].vertices.isEmpty()) {
continue;
}
const glm::vec3* source = _geometry.blendshapes[i].vertices.constData();
@ -147,8 +147,9 @@ void BlendFace::setRig(const fsMsgRig& rig) {
for (vector<fsVertexData>::const_iterator it = rig.blendshapes().begin(), end = rig.blendshapes().end(); it != end; it++) {
FBXBlendshape blendshape;
for (int i = 0, n = it->m_vertices.size(); i < n; i++) {
// subtract the base vertex position; we want the deltas
blendshape.vertices.append(createVec3(it->m_vertices[i]) - geometry.vertices[i]);
blendshape.indices.append(i);
blendshape.vertices.append(createVec3(it->m_vertices[i]));
}
geometry.blendshapes.append(blendshape);
}
@ -210,12 +211,4 @@ void BlendFace::setGeometry(const FBXGeometry& geometry) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
_geometry = geometry;
// subtract the neutral locations from the blend shapes; we want the deltas
for (QVector<FBXBlendshape>::iterator it = _geometry.blendshapes.begin(); it != _geometry.blendshapes.end(); it++) {
glm::vec3* offset = it->vertices.data();
for (const int* index = it->indices.constData(), *end = index + it->indices.size(); index != end; index++, offset++) {
*offset -= geometry.vertices[*index];
}
}
}

View file

@ -192,6 +192,71 @@ QVector<glm::vec3> createVec3Vector(const QVector<double>& doubleVector) {
return values;
}
const char* FACESHIFT_BLENDSHAPES[] = {
"EyeBlink_L",
"EyeBlink_R",
"EyeSquint_L",
"EyeSquint_R",
"EyeDown_L",
"EyeDown_R",
"EyeIn_L",
"EyeIn_R",
"EyeOpen_L",
"EyeOpen_R",
"EyeOut_L",
"EyeOut_R",
"EyeUp_L",
"EyeUp_R",
"BrowsD_L",
"BrowsD_R",
"BrowsU_C",
"BrowsU_L",
"BrowsU_R",
"JawFwd",
"JawLeft",
"JawOpen",
"JawChew",
"JawRight",
"MouthLeft",
"MouthRight",
"MouthFrown_L",
"MouthFrown_R",
"MouthSmile_L",
"MouthSmile_R",
"MouthDimple_L",
"MouthDimple_R",
"LipsStretch_L",
"LipsStretch_R",
"LipsUpperClose",
"LipsLowerClose",
"LipsUpperUp",
"LipsLowerDown",
"LipsUpperOpen",
"LipsLowerOpen",
"LipsFunnel",
"LipsPucker",
"ChinLowerRaise",
"ChinUpperRaise",
"Sneer",
"Puff",
"CheekSquint_L",
"CheekSquint_R",
""
};
QHash<QByteArray, int> createBlendshapeMap() {
QHash<QByteArray, int> map;
for (int i = 0;; i++) {
QByteArray name = FACESHIFT_BLENDSHAPES[i];
if (name != "") {
map.insert(name, i);
} else {
return map;
}
}
}
FBXGeometry extractFBXGeometry(const FBXNode& node) {
FBXGeometry geometry;
@ -271,8 +336,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
// the name is followed by a null and some type info
QByteArray name = object.properties.at(1).toByteArray();
name = name.left(name.indexOf('\0'));
geometry.blendshapes.append(blendshape);
static QHash<QByteArray, int> blendshapeMap = createBlendshapeMap();
int index = blendshapeMap.value(name.left(name.indexOf('\0')));
geometry.blendshapes.resize(qMax(geometry.blendshapes.size(), index + 1));
geometry.blendshapes[index] = blendshape;
}
}
}