Merge pull request #974 from ey6es/blendface

Render blended faces as solid and remove the "Use Faceshift Rig" option (which isn't visible to others).
This commit is contained in:
Philip Rosedale 2013-09-23 13:25:52 -07:00
commit 297652a83b
9 changed files with 25 additions and 87 deletions

View file

@ -275,8 +275,6 @@ Menu::Menu() :
appInstance->getGlowEffect(),
SLOT(cycleRenderMode()));
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::UseFaceshiftRig, 0, false,
appInstance->getFaceshift(), SLOT(setUsingRig(bool)));
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::UsePerlinFace, 0, false);
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtVectors, 0, true);
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::LookAtIndicator, 0, true);

View file

@ -199,7 +199,6 @@ namespace MenuOption {
const QString TestRaveGlove = "Test Rave Glove";
const QString TreeStats = "Calculate Tree Stats";
const QString TransmitterDrive = "Transmitter Drive";
const QString UseFaceshiftRig = "Use Faceshift Rig";
const QString UsePerlinFace = "Use Perlin's Face";
const QString Quit = "Quit";
const QString Webcam = "Webcam";

View file

@ -46,12 +46,13 @@ bool BlendFace::render(float alpha) {
glScalef(_owningHead->getScale() * MODEL_SCALE, _owningHead->getScale() * MODEL_SCALE,
-_owningHead->getScale() * MODEL_SCALE);
glColor4f(1.0f, 1.0f, 1.0f, alpha);
// start with the base
int vertexCount = _geometry.vertices.size();
int normalCount = _geometry.normals.size();
_blendedVertices.resize(vertexCount);
_blendedNormals.resize(normalCount);
memcpy(_blendedVertices.data(), _geometry.vertices.constData(), vertexCount * sizeof(glm::vec3));
memcpy(_blendedNormals.data(), _geometry.normals.constData(), normalCount * sizeof(glm::vec3));
// blend in each coefficient
const vector<float>& coefficients = _owningHead->getBlendshapeCoefficients();
@ -60,31 +61,44 @@ bool BlendFace::render(float alpha) {
if (coefficient == 0.0f || i >= _geometry.blendshapes.size() || _geometry.blendshapes[i].vertices.isEmpty()) {
continue;
}
const glm::vec3* source = _geometry.blendshapes[i].vertices.constData();
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
float normalCoefficient = coefficient * NORMAL_COEFFICIENT_SCALE;
const glm::vec3* vertex = _geometry.blendshapes[i].vertices.constData();
const glm::vec3* normal = _geometry.blendshapes[i].normals.constData();
for (const int* index = _geometry.blendshapes[i].indices.constData(),
*end = index + _geometry.blendshapes[i].indices.size(); index != end; index++, source++) {
_blendedVertices[*index] += *source * coefficient;
*end = index + _geometry.blendshapes[i].indices.size(); index != end; index++, vertex++, normal++) {
_blendedVertices[*index] += *vertex * coefficient;
_blendedNormals[*index] += *normal * normalCoefficient;
}
}
// use the head skin color
glColor4f(_owningHead->getSkinColor().r, _owningHead->getSkinColor().g, _owningHead->getSkinColor().b, alpha);
// update the blended vertices
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * sizeof(glm::vec3), _blendedVertices.constData());
glBufferSubData(GL_ARRAY_BUFFER, vertexCount * sizeof(glm::vec3),
normalCount * sizeof(glm::vec3), _blendedNormals.constData());
// tell OpenGL where to find vertex information
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3)));
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// enable normalization under the expectation that the GPU can do it faster
glEnable(GL_NORMALIZE);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, _geometry.quadIndices.size(), GL_UNSIGNED_INT, 0);
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, _geometry.triangleIndices.size(), GL_UNSIGNED_INT,
(void*)(_geometry.quadIndices.size() * sizeof(int)));
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_NORMALIZE);
// deactivate vertex arrays after drawing
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
// bind with 0 to switch back to normal operation
@ -129,41 +143,6 @@ glm::vec3 createVec3(const fsVector3f& vector) {
return glm::vec3(vector.x, vector.y, vector.z);
}
void BlendFace::setRig(const fsMsgRig& rig) {
// convert to FBX geometry
FBXGeometry geometry;
for (vector<fsVector4i>::const_iterator it = rig.mesh().m_quads.begin(), end = rig.mesh().m_quads.end(); it != end; it++) {
geometry.quadIndices.append(it->x);
geometry.quadIndices.append(it->y);
geometry.quadIndices.append(it->z);
geometry.quadIndices.append(it->w);
}
for (vector<fsVector3i>::const_iterator it = rig.mesh().m_tris.begin(), end = rig.mesh().m_tris.end(); it != end; it++) {
geometry.triangleIndices.append(it->x);
geometry.triangleIndices.append(it->y);
geometry.triangleIndices.append(it->z);
}
for (vector<fsVector3f>::const_iterator it = rig.mesh().m_vertex_data.m_vertices.begin(),
end = rig.mesh().m_vertex_data.m_vertices.end(); it != end; it++) {
geometry.vertices.append(glm::vec3(it->x, it->y, it->z));
}
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);
}
geometry.blendshapes.append(blendshape);
}
setGeometry(geometry);
}
void BlendFace::handleModelDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
if (bytesReceived < bytesTotal && !_modelReply->isFinished()) {
return;
@ -214,7 +193,8 @@ void BlendFace::setGeometry(const FBXGeometry& geometry) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferData(GL_ARRAY_BUFFER, geometry.vertices.size() * sizeof(glm::vec3), NULL, GL_DYNAMIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, (geometry.vertices.size() + geometry.normals.size()) * sizeof(glm::vec3),
NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
_geometry = geometry;

View file

@ -12,8 +12,6 @@
#include <QObject>
#include <QUrl>
#include <fsbinarystream.h>
#include "InterfaceConfig.h"
#include "renderer/FBXReader.h"
@ -36,10 +34,6 @@ public:
Q_INVOKABLE void setModelURL(const QUrl& url);
const QUrl& getModelURL() const { return _modelURL; }
public slots:
void setRig(const fs::fsMsgRig& rig);
private slots:
@ -61,6 +55,7 @@ private:
FBXGeometry _geometry;
QVector<glm::vec3> _blendedVertices;
QVector<glm::vec3> _blendedNormals;
};
#endif /* defined(__interface__BlendFace__) */

View file

@ -66,6 +66,7 @@ public:
float getScale() const { return _scale; }
glm::vec3 getPosition() const { return _position; }
const glm::vec3& getSkinColor() const { return _skinColor; }
const glm::vec3& getEyePosition() const { return _eyePosition; }
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
glm::vec3 getUpDirection() const { return getOrientation() * IDENTITY_UP; }

View file

@ -59,14 +59,6 @@ MyAvatar::MyAvatar(Node* owningNode) :
_collisionRadius = _height * COLLISION_RADIUS_SCALE;
}
void MyAvatar::init() {
Avatar::init();
// when we receive a Faceshift rig, apply it to our own blend face
_head.getBlendFace().connect(Application::getInstance()->getFaceshift(), SIGNAL(rigReceived(fs::fsMsgRig)),
SLOT(setRig(fs::fsMsgRig)));
}
void MyAvatar::reset() {
_head.reset();
_hand.reset();

View file

@ -15,7 +15,6 @@ class MyAvatar : public Avatar {
public:
MyAvatar(Node* owningNode = NULL);
void init();
void reset();
void simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity);
void updateFromGyrosAndOrWebcam(bool gyroLook, float pitchFromTouch);

View file

@ -87,17 +87,6 @@ void Faceshift::setTCPEnabled(bool enabled) {
}
}
void Faceshift::setUsingRig(bool usingRig) {
if (usingRig && _tcpSocket.state() == QAbstractSocket::ConnectedState) {
string message;
fsBinaryStream::encode_message(message, fsMsgSendRig());
send(message);
} else {
emit rigReceived(fsMsgRig());
}
}
void Faceshift::connectSocket() {
if (_tcpEnabled) {
qDebug("Faceshift: Connecting...\n");
@ -114,11 +103,6 @@ void Faceshift::noteConnected() {
string message;
fsBinaryStream::encode_message(message, fsMsgSendBlendshapeNames());
send(message);
// if using faceshift rig, request it
if (Menu::getInstance()->isOptionChecked(MenuOption::UseFaceshiftRig)) {
setUsingRig(true);
}
}
void Faceshift::noteError(QAbstractSocket::SocketError error) {
@ -214,11 +198,6 @@ void Faceshift::receive(const QByteArray& buffer) {
}
break;
}
case fsMsg::MSG_OUT_RIG: {
fsMsgRig* rig = static_cast<fsMsgRig*>(msg.get());
emit rigReceived(*rig);
break;
}
default:
break;
}

View file

@ -60,15 +60,10 @@ public:
void update();
void reset();
signals:
void rigReceived(const fs::fsMsgRig& rig);
public slots:
void setTCPEnabled(bool enabled);
void setUsingRig(bool usingRig);
private slots: