mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 22:16:58 +02:00
Map the blendshapes by name.
This commit is contained in:
parent
116a4e0bad
commit
fff10375a9
2 changed files with 72 additions and 12 deletions
|
@ -55,7 +55,7 @@ bool BlendFace::render(float alpha) {
|
||||||
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
|
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
|
||||||
for (int i = 0; i < coefficients.size(); i++) {
|
for (int i = 0; i < coefficients.size(); i++) {
|
||||||
float coefficient = coefficients[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;
|
continue;
|
||||||
}
|
}
|
||||||
const glm::vec3* source = _geometry.blendshapes[i].vertices.constData();
|
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++) {
|
for (vector<fsVertexData>::const_iterator it = rig.blendshapes().begin(), end = rig.blendshapes().end(); it != end; it++) {
|
||||||
FBXBlendshape blendshape;
|
FBXBlendshape blendshape;
|
||||||
for (int i = 0, n = it->m_vertices.size(); i < n; i++) {
|
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.indices.append(i);
|
||||||
blendshape.vertices.append(createVec3(it->m_vertices[i]));
|
|
||||||
}
|
}
|
||||||
geometry.blendshapes.append(blendshape);
|
geometry.blendshapes.append(blendshape);
|
||||||
}
|
}
|
||||||
|
@ -210,12 +211,4 @@ void BlendFace::setGeometry(const FBXGeometry& geometry) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
_geometry = geometry;
|
_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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,71 @@ QVector<glm::vec3> createVec3Vector(const QVector<double>& doubleVector) {
|
||||||
return values;
|
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 extractFBXGeometry(const FBXNode& node) {
|
||||||
FBXGeometry geometry;
|
FBXGeometry geometry;
|
||||||
|
|
||||||
|
@ -271,8 +336,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
|
||||||
|
|
||||||
// the name is followed by a null and some type info
|
// the name is followed by a null and some type info
|
||||||
QByteArray name = object.properties.at(1).toByteArray();
|
QByteArray name = object.properties.at(1).toByteArray();
|
||||||
name = name.left(name.indexOf('\0'));
|
static QHash<QByteArray, int> blendshapeMap = createBlendshapeMap();
|
||||||
geometry.blendshapes.append(blendshape);
|
int index = blendshapeMap.value(name.left(name.indexOf('\0')));
|
||||||
|
geometry.blendshapes.resize(qMax(geometry.blendshapes.size(), index + 1));
|
||||||
|
geometry.blendshapes[index] = blendshape;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue