mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:13:38 +02:00
Working on reading and rendering the rig from Faceshift.
This commit is contained in:
parent
86307ea67f
commit
f9426cbecc
10 changed files with 193 additions and 9 deletions
|
@ -275,7 +275,8 @@ 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);
|
||||
|
|
|
@ -31,6 +31,8 @@ struct ViewFrustumOffset {
|
|||
float up;
|
||||
};
|
||||
|
||||
class QSettings;
|
||||
|
||||
class BandwidthDialog;
|
||||
class VoxelStatsDialog;
|
||||
|
||||
|
@ -197,6 +199,7 @@ 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";
|
||||
|
|
94
interface/src/avatar/BlendFace.cpp
Normal file
94
interface/src/avatar/BlendFace.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// BlendFace.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/16/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "BlendFace.h"
|
||||
#include "Head.h"
|
||||
|
||||
using namespace fs;
|
||||
|
||||
BlendFace::BlendFace(Head* owningHead) :
|
||||
_owningHead(owningHead),
|
||||
_iboID(0)
|
||||
{
|
||||
}
|
||||
|
||||
BlendFace::~BlendFace() {
|
||||
if (_iboID != 0) {
|
||||
glDeleteBuffers(1, &_iboID);
|
||||
glDeleteBuffers(1, &_vboID);
|
||||
}
|
||||
}
|
||||
|
||||
bool BlendFace::render(float alpha) {
|
||||
if (_iboID == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(_owningHead->getPosition().x, _owningHead->getPosition().y, _owningHead->getPosition().z);
|
||||
glm::quat orientation = _owningHead->getOrientation();
|
||||
glm::vec3 axis = glm::axis(orientation);
|
||||
glRotatef(glm::angle(orientation), axis.x, axis.y, axis.z);
|
||||
glScalef(_owningHead->getScale(), _owningHead->getScale(), _owningHead->getScale());
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
|
||||
// update the blended vertices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, _baseVertices.size() * sizeof(fsVector3f), _baseVertices.data());
|
||||
|
||||
// tell OpenGL where to find vertex information
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, _baseVertices.size() - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
// deactivate vertex arrays after drawing
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// bind with 0 to switch back to normal operation
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlendFace::setRig(const fsMsgRig& rig) {
|
||||
if (rig.mesh().m_tris.empty()) {
|
||||
// clear any existing geometry
|
||||
if (_iboID != 0) {
|
||||
glDeleteBuffers(1, &_iboID);
|
||||
glDeleteBuffers(1, &_vboID);
|
||||
_iboID = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_iboID == 0) {
|
||||
glGenBuffers(1, &_iboID);
|
||||
glGenBuffers(1, &_vboID);
|
||||
}
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboID);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, rig.mesh().m_tris.size() * sizeof(fsVector3i),
|
||||
rig.mesh().m_tris.data(), GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
|
||||
glBufferData(GL_ARRAY_BUFFER, rig.mesh().m_vertex_data.m_vertices.size() * sizeof(fsVector3f), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
_indexCount = rig.mesh().m_tris.size() * 3;
|
||||
_baseVertices = rig.mesh().m_vertex_data.m_vertices;
|
||||
_blendshapes = rig.blendshapes();
|
||||
}
|
47
interface/src/avatar/BlendFace.h
Normal file
47
interface/src/avatar/BlendFace.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// BlendFace.h
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/16/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__BlendFace__
|
||||
#define __interface__BlendFace__
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <fsbinarystream.h>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class Head;
|
||||
|
||||
/// A face formed from a linear mix of blendshapes according to a set of coefficients.
|
||||
class BlendFace : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
BlendFace(Head* owningHead);
|
||||
~BlendFace();
|
||||
|
||||
bool render(float alpha);
|
||||
|
||||
private slots:
|
||||
|
||||
void setRig(const fs::fsMsgRig& rig);
|
||||
|
||||
private:
|
||||
|
||||
Head* _owningHead;
|
||||
|
||||
GLuint _iboID;
|
||||
GLuint _vboID;
|
||||
|
||||
GLsizei _indexCount;
|
||||
std::vector<fs::fsVector3f> _baseVertices;
|
||||
std::vector<fs::fsVertexData> _blendshapes;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__BlendFace__) */
|
|
@ -87,7 +87,8 @@ Head::Head(Avatar* owningAvatar) :
|
|||
_cameraFollowsHead(false),
|
||||
_cameraFollowHeadRate(0.0f),
|
||||
_face(this),
|
||||
_perlinFace(this)
|
||||
_perlinFace(this),
|
||||
_blendFace(this)
|
||||
{
|
||||
if (USING_PHYSICAL_MOHAWK) {
|
||||
resetHairPhysics();
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
#include <VoxelConstants.h>
|
||||
|
||||
#include "BendyLine.h"
|
||||
#include "BlendFace.h"
|
||||
#include "Face.h"
|
||||
#include "PerlinFace.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "PerlinFace.h"
|
||||
#include "world.h"
|
||||
#include "devices/SerialInterface.h"
|
||||
|
||||
|
@ -71,6 +72,7 @@ public:
|
|||
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
|
||||
|
||||
Face& getFace() { return _face; }
|
||||
BlendFace& getBlendFace() { return _blendFace; }
|
||||
|
||||
const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected)
|
||||
float getAverageLoudness() const { return _averageLoudness; }
|
||||
|
@ -128,6 +130,7 @@ private:
|
|||
float _cameraFollowHeadRate;
|
||||
Face _face;
|
||||
PerlinFace _perlinFace;
|
||||
BlendFace _blendFace;
|
||||
|
||||
static ProgramObject _irisProgram;
|
||||
static GLuint _irisTextureID;
|
||||
|
|
|
@ -56,7 +56,15 @@ MyAvatar::MyAvatar(Node* owningNode) :
|
|||
_driveKeys[i] = false;
|
||||
}
|
||||
|
||||
_collisionRadius = _height * COLLISION_RADIUS_SCALE;
|
||||
_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() {
|
||||
|
|
|
@ -15,6 +15,7 @@ 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);
|
||||
|
@ -87,4 +88,4 @@ public:
|
|||
void checkForMouseRayTouching();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <SharedUtil.h>
|
||||
|
||||
#include "Faceshift.h"
|
||||
#include "Menu.h"
|
||||
|
||||
using namespace fs;
|
||||
using namespace std;
|
||||
|
@ -98,6 +99,17 @@ 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,6 +126,11 @@ 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) {
|
||||
|
@ -208,10 +225,10 @@ void Faceshift::receive(const QByteArray& buffer) {
|
|||
} else if (names[i] == "EyeBlink_R") {
|
||||
_rightBlinkIndex = i;
|
||||
|
||||
}else if (names[i] == "EyeOpen_L") {
|
||||
} else if (names[i] == "EyeOpen_L") {
|
||||
_leftEyeOpenIndex = i;
|
||||
|
||||
}else if (names[i] == "EyeOpen_R") {
|
||||
} else if (names[i] == "EyeOpen_R") {
|
||||
_rightEyeOpenIndex = i;
|
||||
|
||||
} else if (names[i] == "BrowsD_L") {
|
||||
|
@ -237,11 +254,15 @@ void Faceshift::receive(const QByteArray& buffer) {
|
|||
|
||||
} else if (names[i] == "MouthSmile_R") {
|
||||
_mouthSmileRightIndex = i;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case fsMsg::MSG_OUT_RIG: {
|
||||
fsMsgRig* rig = static_cast<fsMsgRig*>(msg.get());
|
||||
emit rigReceived(*rig);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -57,10 +57,15 @@ public:
|
|||
void update();
|
||||
void reset();
|
||||
|
||||
signals:
|
||||
|
||||
void rigReceived(const fs::fsMsgRig& rig);
|
||||
|
||||
public slots:
|
||||
|
||||
void setTCPEnabled(bool enabled);
|
||||
|
||||
void setUsingRig(bool usingRig);
|
||||
|
||||
private slots:
|
||||
|
||||
void connectSocket();
|
||||
|
|
Loading…
Reference in a new issue