mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:23:36 +02:00
Pupil dilation.
This commit is contained in:
parent
a44d665767
commit
91999dfe1f
12 changed files with 123 additions and 19 deletions
|
@ -17,6 +17,7 @@
|
|||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMainWindow>
|
||||
#include <QSlider>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -749,6 +750,10 @@ void Menu::editPreferences() {
|
|||
faceURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Face URL:", faceURL);
|
||||
|
||||
QSlider* pupilDilation = new QSlider(Qt::Horizontal);
|
||||
pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum());
|
||||
form->addRow("Pupil Dilation:", pupilDilation);
|
||||
|
||||
QSpinBox* fieldOfView = new QSpinBox();
|
||||
fieldOfView->setMaximum(180);
|
||||
fieldOfView->setMinimum(1);
|
||||
|
@ -790,6 +795,8 @@ void Menu::editPreferences() {
|
|||
|
||||
Avatar::sendAvatarURLsMessage(avatarVoxelURL, faceModelURL);
|
||||
|
||||
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
|
||||
|
||||
_gyroCameraSensitivity = gyroCameraSensitivity->value();
|
||||
|
||||
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
||||
|
|
|
@ -770,6 +770,7 @@ void Avatar::loadData(QSettings* settings) {
|
|||
|
||||
_voxels.setVoxelURL(settings->value("voxelURL").toUrl());
|
||||
_head.getBlendFace().setModelURL(settings->value("faceModelURL").toUrl());
|
||||
_head.setPupilDilation(settings->value("pupilDilation", 0.0f).toFloat());
|
||||
|
||||
_leanScale = loadSetting(settings, "leanScale", 0.05f);
|
||||
|
||||
|
@ -822,6 +823,7 @@ void Avatar::saveData(QSettings* set) {
|
|||
|
||||
set->setValue("voxelURL", _voxels.getVoxelURL());
|
||||
set->setValue("faceModelURL", _head.getBlendFace().getModelURL());
|
||||
set->setValue("pupilDilation", _head.getPupilDilation());
|
||||
|
||||
set->setValue("leanScale", _leanScale);
|
||||
set->setValue("scale", _newScale);
|
||||
|
|
|
@ -28,7 +28,7 @@ BlendFace::~BlendFace() {
|
|||
}
|
||||
|
||||
ProgramObject BlendFace::_eyeProgram;
|
||||
GLuint BlendFace::_eyeTextureID;
|
||||
DilatedTextureCache BlendFace::_eyeTextureCache("resources/images/eye.png", 50, 210);
|
||||
|
||||
void BlendFace::init() {
|
||||
if (!_eyeProgram.isLinked()) {
|
||||
|
@ -40,8 +40,6 @@ void BlendFace::init() {
|
|||
_eyeProgram.bind();
|
||||
_eyeProgram.setUniformValue("texture", 0);
|
||||
_eyeProgram.release();
|
||||
|
||||
_eyeTextureID = Application::getInstance()->getTextureCache()->getFileTextureID("resources/images/eye.png");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +90,9 @@ bool BlendFace::render(float alpha) {
|
|||
// use texture coordinates only for the eye, for now
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _eyeTextureID);
|
||||
_eyeTexture = _eyeTextureCache.getTexture(_owningHead->getPupilDilation());
|
||||
glBindTexture(GL_TEXTURE_2D, _eyeTexture->getID());
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
_eyeProgram.bind();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "InterfaceConfig.h"
|
||||
#include "renderer/FBXReader.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
#include "renderer/TextureCache.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
|
@ -62,8 +63,10 @@ private:
|
|||
QVector<glm::vec3> _blendedVertices;
|
||||
QVector<glm::vec3> _blendedNormals;
|
||||
|
||||
QSharedPointer<Texture> _eyeTexture;
|
||||
|
||||
static ProgramObject _eyeProgram;
|
||||
static GLuint _eyeTextureID;
|
||||
static DilatedTextureCache _eyeTextureCache;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__BlendFace__) */
|
||||
|
|
|
@ -29,7 +29,7 @@ const float EYEBALL_RADIUS = 0.017;
|
|||
const float EYELID_RADIUS = 0.019;
|
||||
const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f };
|
||||
|
||||
const float HAIR_SPRING_FORCE = 15.0f;
|
||||
const float HAIR_SPRING_FORCE = 15.0f;
|
||||
const float HAIR_TORQUE_FORCE = 0.2f;
|
||||
const float HAIR_GRAVITY_FORCE = 0.001f;
|
||||
const float HAIR_DRAG = 10.0f;
|
||||
|
@ -46,7 +46,7 @@ const float IRIS_PROTRUSION = 0.0145f;
|
|||
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
|
||||
|
||||
ProgramObject Head::_irisProgram;
|
||||
GLuint Head::_irisTextureID;
|
||||
DilatedTextureCache Head::_irisTextureCache(IRIS_TEXTURE_FILENAME, 53, 127);
|
||||
int Head::_eyePositionLocation;
|
||||
|
||||
Head::Head(Avatar* owningAvatar) :
|
||||
|
@ -102,13 +102,6 @@ void Head::init() {
|
|||
|
||||
_irisProgram.setUniformValue("texture", 0);
|
||||
_eyePositionLocation = _irisProgram.uniformLocation("eyePosition");
|
||||
|
||||
_irisTextureID = Application::getInstance()->getTextureCache()->getFileTextureID(IRIS_TEXTURE_FILENAME);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
_blendFace.init();
|
||||
}
|
||||
|
@ -667,7 +660,12 @@ void Head::renderEyeBalls() {
|
|||
glPopMatrix();
|
||||
|
||||
_irisProgram.bind();
|
||||
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
|
||||
|
||||
_irisTexture = _irisTextureCache.getTexture(_pupilDilation);
|
||||
glBindTexture(GL_TEXTURE_2D, _irisTexture->getID());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// render left iris
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "PerlinFace.h"
|
||||
#include "world.h"
|
||||
#include "devices/SerialInterface.h"
|
||||
#include "renderer/TextureCache.h"
|
||||
|
||||
enum eyeContactTargets {
|
||||
LEFT_EYE,
|
||||
|
@ -135,8 +136,10 @@ private:
|
|||
PerlinFace _perlinFace;
|
||||
BlendFace _blendFace;
|
||||
|
||||
QSharedPointer<Texture> _irisTexture;
|
||||
|
||||
static ProgramObject _irisProgram;
|
||||
static GLuint _irisTextureID;
|
||||
static DilatedTextureCache _irisTextureCache;
|
||||
static int _eyePositionLocation;
|
||||
|
||||
// private methods
|
||||
|
|
|
@ -248,7 +248,11 @@ void PerlinFace::render() {
|
|||
|
||||
|
||||
Head::_irisProgram.bind();
|
||||
glBindTexture(GL_TEXTURE_2D, Head::_irisTextureID);
|
||||
_owningHead->_irisTexture = Head::_irisTextureCache.getTexture(_owningHead->_pupilDilation);
|
||||
glBindTexture(GL_TEXTURE_2D, _owningHead->_irisTexture->getID());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
orientation = _owningHead->getOrientation();
|
||||
|
|
|
@ -154,3 +154,44 @@ QOpenGLFramebufferObject* TextureCache::createFramebufferObject() {
|
|||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
Texture::Texture() {
|
||||
glGenTextures(1, &_id);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
glDeleteTextures(1, &_id);
|
||||
}
|
||||
|
||||
DilatedTextureCache::DilatedTextureCache(const QString& filename, int innerRadius, int outerRadius) :
|
||||
_innerRadius(innerRadius),
|
||||
_outerRadius(outerRadius)
|
||||
{
|
||||
switchToResourcesParentIfRequired();
|
||||
_image = QImage(filename).convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
QSharedPointer<Texture> DilatedTextureCache::getTexture(float dilation) {
|
||||
QSharedPointer<Texture> texture = _textures.value(dilation);
|
||||
if (texture.isNull()) {
|
||||
texture = QSharedPointer<Texture>(new Texture());
|
||||
|
||||
QImage dilatedImage = _image;
|
||||
QPainter painter;
|
||||
painter.begin(&dilatedImage);
|
||||
QPainterPath path;
|
||||
qreal radius = glm::mix(_innerRadius, _outerRadius, dilation);
|
||||
path.addEllipse(QPointF(_image.width() / 2.0, _image.height() / 2.0), radius, radius);
|
||||
painter.fillPath(path, Qt::black);
|
||||
painter.end();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getID());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_textures.insert(dilation, texture);
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
#define __interface__TextureCache__
|
||||
|
||||
#include <QHash>
|
||||
#include <QImage>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QWeakPointer>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
|
@ -62,4 +66,36 @@ private:
|
|||
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
|
||||
};
|
||||
|
||||
/// A simple object wrapper for an OpenGL texture.
|
||||
class Texture {
|
||||
public:
|
||||
|
||||
Texture();
|
||||
~Texture();
|
||||
|
||||
GLuint getID() const { return _id; }
|
||||
|
||||
private:
|
||||
|
||||
GLuint _id;
|
||||
};
|
||||
|
||||
/// Caches textures according to pupillary dilation.
|
||||
class DilatedTextureCache {
|
||||
public:
|
||||
|
||||
DilatedTextureCache(const QString& filename, int innerRadius, int outerRadius);
|
||||
|
||||
/// Returns a pointer to a texture with the requested amount of dilation.
|
||||
QSharedPointer<Texture> getTexture(float dilation);
|
||||
|
||||
private:
|
||||
|
||||
QImage _image;
|
||||
int _innerRadius;
|
||||
int _outerRadius;
|
||||
|
||||
QMap<float, QWeakPointer<Texture> > _textures;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__TextureCache__) */
|
||||
|
|
|
@ -211,6 +211,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
destinationBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float);
|
||||
}
|
||||
|
||||
// pupil dilation
|
||||
destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f);
|
||||
|
||||
// leap hand data
|
||||
destinationBuffer += _handData->encodeRemoteData(destinationBuffer);
|
||||
|
||||
|
@ -345,7 +348,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
_headData->_blendshapeCoefficients.size() * sizeof(float));
|
||||
sourceBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float);
|
||||
}
|
||||
|
||||
|
||||
// pupil dilation
|
||||
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
|
||||
|
||||
// leap hand data
|
||||
if (sourceBuffer - startPosition < numBytes) {
|
||||
// check passed, bytes match
|
||||
|
|
|
@ -46,6 +46,9 @@ public:
|
|||
|
||||
const std::vector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||
|
||||
float getPupilDilation() const { return _pupilDilation; }
|
||||
void setPupilDilation(float pupilDilation) { _pupilDilation = pupilDilation; }
|
||||
|
||||
void addYaw(float yaw);
|
||||
void addPitch(float pitch);
|
||||
void addRoll(float roll);
|
||||
|
@ -70,6 +73,7 @@ protected:
|
|||
float _averageLoudness;
|
||||
float _browAudioLift;
|
||||
std::vector<float> _blendshapeCoefficients;
|
||||
float _pupilDilation;
|
||||
AvatarData* _owningAvatar;
|
||||
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
|||
return 1;
|
||||
|
||||
case PACKET_TYPE_HEAD_DATA:
|
||||
return 7;
|
||||
return 8;
|
||||
|
||||
case PACKET_TYPE_AVATAR_URLS:
|
||||
return 1;
|
||||
|
|
Loading…
Reference in a new issue